Subversion Repositories NaviCtrl

Rev

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

Rev 407 Rev 427
Line 5... Line 5...
5
// + www.MikroKopter.com
5
// + www.MikroKopter.com
6
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
6
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
7
// + Software Nutzungsbedingungen (english version: see below)
7
// + Software Nutzungsbedingungen (english version: see below)
8
// + der Fa. HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland - nachfolgend Lizenzgeber genannt -
8
// + der Fa. HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland - nachfolgend Lizenzgeber genannt -
9
// + Der Lizenzgeber räumt dem Kunden ein nicht-ausschließliches, zeitlich und räumlich* unbeschränktes Recht ein, die im den
9
// + Der Lizenzgeber räumt dem Kunden ein nicht-ausschließliches, zeitlich und räumlich* unbeschränktes Recht ein, die im den
10
// + Mikrocontroller verwendete Firmware für die Hardware Flight-Ctrl, Navi-Ctrl, BL-Ctrl, MK3Mag & PC-Programm MikroKopter-Tool 
10
// + Mikrocontroller verwendete Firmware für die Hardware Flight-Ctrl, Navi-Ctrl, BL-Ctrl, MK3Mag & PC-Programm MikroKopter-Tool
11
// + - nachfolgend Software genannt - nur für private Zwecke zu nutzen.
11
// + - nachfolgend Software genannt - nur für private Zwecke zu nutzen.
12
// + Der Einsatz dieser Software ist nur auf oder mit Produkten des Lizenzgebers zulässig.
12
// + Der Einsatz dieser Software ist nur auf oder mit Produkten des Lizenzgebers zulässig.
13
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
13
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
14
// + Die vom Lizenzgeber gelieferte Software ist urheberrechtlich geschützt. Alle Rechte an der Software sowie an sonstigen im
14
// + Die vom Lizenzgeber gelieferte Software ist urheberrechtlich geschützt. Alle Rechte an der Software sowie an sonstigen im
15
// + Rahmen der Vertragsanbahnung und Vertragsdurchführung überlassenen Unterlagen stehen im Verhältnis der Vertragspartner ausschließlich dem Lizenzgeber zu.
15
// + Rahmen der Vertragsanbahnung und Vertragsdurchführung überlassenen Unterlagen stehen im Verhältnis der Vertragspartner ausschließlich dem Lizenzgeber zu.
16
// + Die in der Software enthaltenen Copyright-Vermerke, Markenzeichen, andere Rechtsvorbehalte, Seriennummern sowie
16
// + Die in der Software enthaltenen Copyright-Vermerke, Markenzeichen, andere Rechtsvorbehalte, Seriennummern sowie
17
// + sonstige der Programmidentifikation dienenden Merkmale dürfen vom Kunden nicht verändert oder unkenntlich gemacht werden.
17
// + sonstige der Programmidentifikation dienenden Merkmale dürfen vom Kunden nicht verändert oder unkenntlich gemacht werden.
18
// + Der Kunde trifft angemessene Vorkehrungen für den sicheren Einsatz der Software. Er wird die Software gründlich auf deren
18
// + Der Kunde trifft angemessene Vorkehrungen für den sicheren Einsatz der Software. Er wird die Software gründlich auf deren
19
// + Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt.
19
// + Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt.
20
// + Die Haftung des Lizenzgebers wird - soweit gesetzlich zulässig - begrenzt in Höhe des typischen und vorhersehbaren
20
// + Die Haftung des Lizenzgebers wird - soweit gesetzlich zulässig - begrenzt in Höhe des typischen und vorhersehbaren
21
// + Schadens. Die gesetzliche Haftung bei Personenschäden und nach dem Produkthaftungsgesetz bleibt unberührt. Dem Lizenzgeber steht jedoch der Einwand 
21
// + Schadens. Die gesetzliche Haftung bei Personenschäden und nach dem Produkthaftungsgesetz bleibt unberührt. Dem Lizenzgeber steht jedoch der Einwand
22
// + des Mitverschuldens offen.
22
// + des Mitverschuldens offen.
23
// + Der Kunde trifft angemessene Vorkehrungen für den Fall, dass die Software ganz oder teilweise nicht ordnungsgemäß arbeitet.
23
// + Der Kunde trifft angemessene Vorkehrungen für den Fall, dass die Software ganz oder teilweise nicht ordnungsgemäß arbeitet.
24
// + Er wird die Software gründlich auf deren Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt.
24
// + Er wird die Software gründlich auf deren Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt.
25
// + Der Kunde wird er seine Daten vor Einsatz der Software nach dem Stand der Technik sichern.
25
// + Der Kunde wird er seine Daten vor Einsatz der Software nach dem Stand der Technik sichern.
26
// + Der Kunde ist darüber unterrichtet, dass der Lizenzgeber seine Daten im zur Vertragsdurchführung erforderlichen Umfang
26
// + Der Kunde ist darüber unterrichtet, dass der Lizenzgeber seine Daten im zur Vertragsdurchführung erforderlichen Umfang
Line 30... Line 30...
30
// +  Hinweis: Informationen über erweiterte Nutzungsrechte (wie z.B. Nutzung für nicht-private Zwecke) sind auf Anfrage per Email an info(@)hisystems.de verfügbar.
30
// +  Hinweis: Informationen über erweiterte Nutzungsrechte (wie z.B. Nutzung für nicht-private Zwecke) sind auf Anfrage per Email an info(@)hisystems.de verfügbar.
31
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
31
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
32
// + Software LICENSING TERMS
32
// + Software LICENSING TERMS
33
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
33
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
34
// + of HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland, Germany - the Licensor -
34
// + of HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland, Germany - the Licensor -
35
// + The Licensor grants the customer a non-exclusive license to use the microcontroller firmware of the Flight-Ctrl, Navi-Ctrl, BL-Ctrl, and MK3Mag hardware 
35
// + The Licensor grants the customer a non-exclusive license to use the microcontroller firmware of the Flight-Ctrl, Navi-Ctrl, BL-Ctrl, and MK3Mag hardware
36
// + (the Software) exclusively for private purposes. The License is unrestricted with respect to time and territory*.
36
// + (the Software) exclusively for private purposes. The License is unrestricted with respect to time and territory*.
37
// + The Software may only be used with the Licensor's products.
37
// + The Software may only be used with the Licensor's products.
38
// + The Software provided by the Licensor is protected by copyright. With respect to the relationship between the parties to this
38
// + The Software provided by the Licensor is protected by copyright. With respect to the relationship between the parties to this
39
// + agreement, all rights pertaining to the Software and other documents provided during the preparation and execution of this
39
// + agreement, all rights pertaining to the Software and other documents provided during the preparation and execution of this
40
// + agreement shall be the property of the Licensor.
40
// + agreement shall be the property of the Licensor.
Line 60... Line 60...
60
#include "fat16.h"
60
#include "fat16.h"
61
#include "sdc.h"
61
#include "sdc.h"
62
#include "uart1.h"
62
#include "uart1.h"
63
#include "main.h"
63
#include "main.h"
64
#include "logging.h"
64
#include "logging.h"
-
 
65
#include "debug.h"
Line 65... Line 66...
65
 
66
 
66
 
67
 
67
//________________________________________________________________________________________________________________________________________
68
//________________________________________________________________________________________________________________________________________
68
// Module name:                 fat16.c
69
// Module name:                 fat16.c
69
// Compiler used:               avr-gcc 3.4.5
70
// Compiler used:               avr-gcc 3.4.5
70
// Last Modifikation:   20.03.2010
71
// Last Modifikation:   1.12.2012
71
// Version:                             2.10
72
// Version:                             2.11
72
// Authors:                             Stephan Busker & Gregor Stobrawa
73
// Authors:                             Stephan Busker & Gregor Stobrawa
73
// Description:                 Source files for FAT16 implementation with read and write-access
74
// Description:                 Source files for FAT16 implementation with read and write-access
74
//                                              Copyright (C) 2008 Stephan Busker & Gregor Stobrawa
75
//                                              Copyright (C) 2008 Stephan Busker & Gregor Stobrawa
75
//........................................................................................................................................
76
//........................................................................................................................................
76
// Functions:                   extern s16              Fat16_Init(void);
77
// Functions:                   extern s16              Fat16_Init(void);
-
 
78
//                                              extern s16              Fat16_Deinit(void);
77
//                                              extern s16              Fat16_Deinit(void);
79
//                                              extern s8*              FAT16_GetVolumeLabel(void);
78
//                                              extern s8*              FAT16_GetVolumeLabel(void);
80
//
79
//                                              extern File_t * fopen_(const u8 *filename, const s8 mode);
81
//                                              extern File_t * fopen_(const u8 *filename, const s8 mode);
80
//                                              extern s16              fclose_(File_t *File);
82
//                                              extern s16              fclose_(File_t *file);
81
//                                              extern u8               fexist_(s8 * const filename);
83
//                                              extern u8               fexist_(s8 * const filename);
82
//                                              extern s16              fflush_(File_t *File);
84
//                                              extern s16              fflush_(File_t *file);
83
//                                              extern s16      fseek_(File_t *File, s32 offset, s16 origin);
85
//                                              extern s16      fseek_(File_t *file, s32 offset, s16 origin);
84
//                                              extern s16              fgetc_(File_t *File);
86
//                                              extern s16              fgetc_(File_t *file);
85
//                                              extern s16              fputc_(u8 c, File_t *File);
87
//                                              extern s16              fputc_(u8 c, File_t *file);
86
//                                              extern u32              fread_(void *buffer, u32 size, u32 count, File_t *File);
88
//                                              extern u32              fread_(void *buffer, u32 size, u32 count, File_t *file);
87
//                                              extern u32              fwrite_(void *buffer, u32 size, u32 count, File_t *File);
89
//                                              extern u32              fwrite_(void *buffer, u32 size, u32 count, File_t *file);
88
//                                              extern s16              fputs_(const u8 *string, File_t *File);
90
//                                              extern s16              fputs_(const u8 *string, File_t *File);
-
 
91
//                                              extern u8 *     fgets_(u8 *string, s16 length, File_t *file);
-
 
92
//                                              extern u8               feof_(File_t * const file);
-
 
93
//                                              extern u8               fdelete_(s8* const filepath);
-
 
94
//
-
 
95
//                                              extern s8               *getcwd_(void);
-
 
96
//                                              extern u8               chdir_(s8* const dirpath);
-
 
97
//                                              extern u8               mkdir_(s8* const dirpath);
-
 
98
//                                              extern u8               rmdir_(s8* const dirpath);
89
//                                              extern u8 *     fgets_(u8 *string, s16 length, File_t *File);
99
//                                              extern u8               findfirst_(const s8* name, u8 attribmask, Find_t *);
90
//                                              extern u8               feof_(File_t * const file);
100
//                                              extern u8               findnext_(Find_t *);
91
//........................................................................................................................................
101
//........................................................................................................................................
92
// ext. functions:              extern SD_Result_t SDC_Init(void;)
102
// ext. functions:              extern SD_Result_t SDC_Init(void;)
93
//                                              extern SD_Result_t SDC_Deinit(void);
103
//                                              extern SD_Result_t SDC_Deinit(void);
Line 249... Line 259...
249
        u16 StartCluster;                               // first cluster of the file or directory.
259
        u16 StartCluster;                               // first cluster of the file or directory.
250
        u32 Size;                                               // size of the file or directory in bytes.
260
        u32 Size;                                               // size of the file or directory in bytes.
251
}  __attribute__((packed)) DirEntry_t;
261
}  __attribute__((packed)) DirEntry_t;
Line 252... Line 262...
252
 
262
 
253
#define SLOT_EMPTY              0x00    // slot has never been used
263
#define SLOT_EMPTY              0x00    // slot has never been used
254
#define SLOT_E5                 0x05    // the real value is 0xe5
264
#define SLOT_E5                 0x05    // the real value is 0xE5
Line 255... Line -...
255
#define SLOT_DELETED            0xE5    // file in this slot deleted
-
 
256
 
-
 
257
#define ATTR_NONE               0x00    // normal file
-
 
258
#define ATTR_READONLY           0x01    // file is readonly
-
 
259
#define ATTR_HIDDEN                     0x02    // file is hidden
-
 
260
#define ATTR_SYSTEM                     0x04    // file is a system file
-
 
261
#define ATTR_VOLUMELABEL        0x08    // entry is a volume label
-
 
262
#define ATTR_LONG_FILENAME      0x0F    // this is a long filename entry
-
 
263
#define ATTR_SUBDIRECTORY       0x10    // entry is a directory name
-
 
264
#define ATTR_ARCHIVE            0x20    // file is new or modified
-
 
265
 
265
#define SLOT_DELETED            0xE5    // file in this slot deleted
266
 
266
 
Line 267... Line 267...
267
/*
267
/*
268
________________________________________________________________________________________________________________________________________
268
________________________________________________________________________________________________________________________________________
Line 314... Line 314...
314
        u32 FirstFatSector;                     // sector of the start of the fat
314
        u32 FirstFatSector;                     // sector of the start of the fat
315
        u32 FirstRootDirSector;         // sector of the rootdirectory
315
        u32 FirstRootDirSector;         // sector of the rootdirectory
316
        u32 FirstDataSector;            // sector of the first cluster containing data (cluster2).
316
        u32 FirstDataSector;            // sector of the first cluster containing data (cluster2).
317
        u32 LastDataSector;                     // the last data sector of the partition
317
        u32 LastDataSector;                     // the last data sector of the partition
318
        u8  VolumeLabel[12];        // the volume label
318
        u8  VolumeLabel[12];        // the volume label
319
        u32     CurrentWorkingDirectory;// A pointer to the directory we are actual using 
319
        u32     CurrentWorkingDirectory;// A pointer to the directory we are actual using
320
        s8      PathToCwd[256];                 // a string containing the complete path to the current working directory                               
320
        s8      PathToCwd[256];                 // a string containing the complete path to the current working directory
321
}   __attribute__((packed)) Partition_t;
321
}   __attribute__((packed)) Partition_t;
Line 322... Line 322...
322
 
322
 
Line 323... Line 323...
323
Partition_t     Partition;              // Structure holds partition information
323
Partition_t     Partition;              // Structure holds partition information
Line -... Line 324...
-
 
324
 
-
 
325
File_t FilePointer[FILE_MAX_OPEN];      // Allocate Memmoryspace for each filepointer used.
-
 
326
 
-
 
327
/********************************************************************************************************************************************/
-
 
328
/*      Function:               s8 *getcwd_(void);                                                                                                                                                                                                              */
-
 
329
/*                                                                                                                                                                                                                                                                                      */
-
 
330
/*      Description:    This function returns a pointer to the absolute path of the active partition                                                                            */
-
 
331
/*                                                                                                                                                                                                                                      */
Line -... Line 332...
-
 
332
/*                                                                                                                                                                                                                                                                                      */
-
 
333
/*      Returnvalue:    pointer to the string containing the path to the CWD                                                                                                                                    */
-
 
334
/********************************************************************************************************************************************/
-
 
335
 
Line -... Line 336...
-
 
336
s8 *getcwd_(void)
-
 
337
{
-
 
338
        return(Partition.PathToCwd);
-
 
339
}
-
 
340
 
-
 
341
/********************************************************************************************************************************************/
-
 
342
/*      Function:               void CWDPath_Push(s8* directory);                                                                                                                                                                               */
-
 
343
/*                                                                                                                                                                                                                                                                                      */
-
 
344
/*      Description:    This function function appends the name of an directory to the path of the CWD                                                                                  */
-
 
345
/*                                                                                                                                                                                                                                      */
-
 
346
/*                                                                                                                                                                                                                                                                                      */
-
 
347
/*      Returnvalue:    none                                                                                                                                                                                                                                    */
-
 
348
/********************************************************************************************************************************************/
-
 
349
 
-
 
350
void CWDPath_Push(s8* directory)
-
 
351
{
-
 
352
        // append the name of the directory to the path
-
 
353
        strcat(Partition.PathToCwd, directory);
-
 
354
        // append a '/' after the directoryname
-
 
355
        strcat(Partition.PathToCwd, "/");
-
 
356
}
-
 
357
 
-
 
358
/********************************************************************************************************************************************/
-
 
359
/*      Function:               CWDPath_Pop(void);                                                                                                                                                                                                              */
-
 
360
/*                                                                                                                                                                                                                                                                                      */
-
 
361
/*      Description:    This function removes the last directory from the path to the CWD                                                                                                               */
-
 
362
/*                                                                                                                                                                                                                                      */
-
 
363
/*                                                                                                                                                                                                                                                                                      */
-
 
364
/*      Returnvalue:    none                                                                                                                                                                                                                                    */
-
 
365
/********************************************************************************************************************************************/
-
 
366
 
-
 
367
void CWDPath_Pop(void)
-
 
368
{
-
 
369
        // a pointer to the beginning of the absolute path to the cwd
-
 
370
        s8 * cptr = Partition.PathToCwd;
-
 
371
        // lets find the end of the path to the cwd
-
 
372
        while(*cptr != 0 ) cptr++;
-
 
373
        // if the path is terminated with an '/' then remove it
-
 
374
        if((*(cptr-1)) == '/') *(cptr-1) = 0;
-
 
375
        // now lets find the beginning of the last directory entry
-
 
376
        while((*cptr != '/' ) && cptr > Partition.PathToCwd) cptr--;
-
 
377
        // is there one subdirectory left within the path?
-
 
378
        if(cptr > Partition.PathToCwd)
-
 
379
        {
-
 
380
                // we delete the direntry by terminating the path with 0
-
 
381
                *(cptr+1) = 0;
-
 
382
        }
-
 
383
        // there is no subdirectory left within the path. Therefore we create the root instead.
-
 
384
        else
Line 324... Line 385...
324
 
385
        {
325
File_t FilePointer[FILE_MAX_OPEN];      // Allocate Memmoryspace for each filepointer used.
386
                *cptr = '/';
326
 
387
                *(cptr+1) = 0;
327
 
388
        }
Line 377... Line 438...
377
{
438
{
378
        u8 i;
439
        u8 i;
379
        File_t * File = 0;
440
        File_t * File = 0;
380
        for(i = 0; i < FILE_MAX_OPEN; i++)
441
        for(i = 0; i < FILE_MAX_OPEN; i++)
381
        {
442
        {
382
                if(FilePointer[i].State == FSTATE_UNUSED)               // found an unused one
443
                if(FilePointer[i].State == FSTATE_UNUSED)                                                               // found an unused one
383
                {
444
                {
384
                        File = &FilePointer[i];                                         // set pointer to that entry
445
                        File = &FilePointer[i];                                                                                         // set pointer to that entry
-
 
446
                        FilePointer[i].FirstSectorOfFirstCluster = SECTOR_UNDEFINED;            // First sector of the first cluster of the file.
-
 
447
                        FilePointer[i].FirstSectorOfCurrCluster = SECTOR_UNDEFINED;                     // First sector of the cluster which is edited at the moment.
-
 
448
                        FilePointer[i].FirstSectorOfLastCluster = SECTOR_UNDEFINED;                     // First sector of the last cluster of the file
-
 
449
                        FilePointer[i].SectorOfCurrCluster = SECTOR_UNDEFINED;                          // The sector within the current cluster.
-
 
450
                        FilePointer[i].ByteOfCurrSector = 0;                                                            // The byte location within the current sector.
-
 
451
                        FilePointer[i].Mode = 0;                                                                                        // Mode of fileoperation (read,write)
-
 
452
                        FilePointer[i].Size = 0;                                                                                        // The size of the opend file in bytes.
-
 
453
                        FilePointer[i].Position = 0;                                                                            // Pointer to a character within the file 0 < fileposition < filesize
-
 
454
                        FilePointer[i].DirectorySector = SECTOR_UNDEFINED;                                      // the sectorposition where the directoryentry has been made.
-
 
455
                        FilePointer[i].DirectoryIndex = 0;                                                                      // The index to the directoryentry within the specified sector.
-
 
456
                        FilePointer[i].Attribute = 0;                                                                           // The attribute of the file opened.
-
 
457
                        FilePointer[i].SectorInCache = SECTOR_UNDEFINED;                                        // The last sector read, which is still in the sector cache.
385
                        FilePointer[i].State = FSTATE_USED;                     // mark it as used
458
                        FilePointer[i].State = FSTATE_USED;                                                                     // mark it as used
-
 
459
 
386
                        break;
460
                        break;
387
                }
461
                }
388
        }
462
        }
389
        return(File);
463
        return(File);
390
}
464
}
Line 422... Line 496...
422
        }
496
        }
423
        return(0);
497
        return(0);
424
}
498
}
Line 425... Line 499...
425
 
499
 
426
/****************************************************************************************************************************************/
500
/****************************************************************************************************************************************/
427
/*      Function:               SeperateDirName(s8*, s8*);                                                                                                                                                                              */
501
/*      Function:               s8* SeperateFormatedDirName(const s8*, s8*);                                                                                                                                            */
428
/*                                                                                                                                                                                                                                                                              */
502
/*                                                                                                                                                                                                                                                                              */
429
/*      Description:    This function seperates the first dirname from filepath and brings them                                                                                         */
503
/*      Description:    This function seperates the first dirname from filepath and brings them                                                                                         */
430
/*                                      into the needed format ('test.txt' -> 'TEST    TXT')                                                                                                                            */
504
/*                                      into the needed format ('test.txt' -> 'TEST    TXT')                                                                                                                            */
431
/*                                      The subpath is the pointer to the remaining substring of the filepath                                                                                           */
505
/*                                      The subpath is the pointer to the remaining substring of the filepath                                                                                           */
432
/*                                                                                                                                                                                                                                                                              */
506
/*                                                                                                                                                                                                                                                                              */
433
/*      Returnvalue:    Return NULL on error or pointer to subpath                                                                                                                                                                                                      */
507
/*      Returnvalue:    Return NULL on error or pointer to subpath                                                                                                                                                      */
434
/****************************************************************************************************************************************/
508
/****************************************************************************************************************************************/
435
s8* SeperateDirName(const s8 *filepath, s8 *dirname)
509
s8* SeperateFormatedDirName(const s8 *filepath, s8 *dirname)
436
{
510
{
437
        s8* subpath = NULL;
511
        s8* subpath = NULL;
438
        u8 readpointer  = 0;
512
        u8 readpointer  = 0;
Line 456... Line 530...
456
        for(writepointer = 0; writepointer < 11; writepointer++) dirname[writepointer] = ' ';
530
        for(writepointer = 0; writepointer < 11; writepointer++) dirname[writepointer] = ' ';
Line 457... Line 531...
457
 
531
 
458
        // handle the special dirnames "." and ".." seperately
532
        // handle the special dirnames "." and ".." seperately
459
        readpointer = 0;
533
        readpointer = 0;
460
        if(filepath[0] == '/') readpointer++;
534
        if(filepath[0] == '/') readpointer++;
461
        // if we are trying to enter directories "." or ".." 
535
        // if we are trying to enter directories "." or ".."
462
        if(filepath[readpointer] == '.')
536
        if(filepath[readpointer] == '.')
463
        {
537
        {
464
                // directory '.'
538
                // directory '.'
465
                if(filepath[readpointer+1] == 0)
539
                if(filepath[readpointer+1] == 0)
466
                {
540
                {
467
                        dirname[0] = '.';
541
                        dirname[0] = '.';
468
                        return((s8*)&filepath[readpointer]);
542
                        return((s8*)&filepath[readpointer]);
469
                }
543
                }
470
                // directory '..'               
544
                // directory '..'
471
                if((filepath[readpointer+1] == '.') &&  (filepath[readpointer+2] == 0))
545
                if((filepath[readpointer+1] == '.') &&  (filepath[readpointer+2] == 0))
472
                {
546
                {
473
                        dirname[0] = '.';
547
                        dirname[0] = '.';
474
                        dirname[1] = '.';
548
                        dirname[1] = '.';
475
                        return((s8*)&filepath[readpointer]);
549
                        return((s8*)&filepath[readpointer]);
Line 507... Line 581...
507
                }
581
                }
508
        }
582
        }
509
        return(subpath);
583
        return(subpath);
510
}
584
}
Line 511... Line -...
511
 
-
 
512
 
585
 
513
/**************************************************************************************************************************************+*/
586
/**************************************************************************************************************************************+*/
514
/*      Function:       Fat16ClusterToSector( u16 cluster);                                                                                                                                                                             */
587
/*      Function:       Fat16ClusterToSector( u16 cluster);                                                                                                                                                                             */
515
/*                                                                                                                                                                                                                                                                              */
588
/*                                                                                                                                                                                                                                                                              */
516
/*      Description:    This function converts a cluster number given by the fat to the corresponding                                                                           */
589
/*      Description:    This function converts a cluster number given by the fat to the corresponding                                                                           */
Line 572... Line 645...
572
        u8 cnt;
645
        u8 cnt;
Line 573... Line 646...
573
 
646
 
574
        UART1_PutString("\r\n FAT16 deinit...");
647
        UART1_PutString("\r\n FAT16 deinit...");
575
        // declare the filepointers as unused.
648
        // declare the filepointers as unused.
576
        for(cnt = 0; cnt < FILE_MAX_OPEN; cnt++)
649
        for(cnt = 0; cnt < FILE_MAX_OPEN; cnt++)
577
        {      
650
        {
578
                UnlockFilePointer(&FilePointer[cnt]);
651
                UnlockFilePointer(&FilePointer[cnt]);
579
        }
652
        }
580
        returnvalue = SDC_Deinit();                     // uninitialize interface to sd-card
653
        returnvalue = SDC_Deinit();                     // uninitialize interface to sd-card
581
        Partition.IsValid = 0;  // mark data in partition structure as invalid
654
        Partition.IsValid = 0;  // mark data in partition structure as invalid
Line 584... Line 657...
584
        if(SD_WatchDog > 2000) SD_WatchDog = 2000;
657
        if(SD_WatchDog > 2000) SD_WatchDog = 2000;
585
        SD_LoggingError = 100;
658
        SD_LoggingError = 100;
586
        return(returnvalue);
659
        return(returnvalue);
587
}
660
}
Line -... Line 661...
-
 
661
 
588
 
662
 
589
/****************************************************************************************************************************************/
663
/****************************************************************************************************************************************/
590
/*      Function:               Fat16_Init(void);                                                                                                                                                                                                       */
664
/*      Function:               Fat16_Init(void);                                                                                                                                                                                                       */
591
/*                                                                                                                                                                                                                                                                          */
665
/*                                                                                                                                                                                                                                                                          */
592
/*      Description:    This function reads the Masterbootrecord and finds the position of the Volumebootrecord, the FAT and the Rootdir    */
666
/*      Description:    This function reads the Masterbootrecord and finds the position of the Volumebootrecord, the FAT and the Rootdir    */
Line 686... Line 760...
686
                result = 6;
760
                result = 6;
687
                goto end;
761
                goto end;
688
        }
762
        }
689
        Partition.IsValid = 1; // mark data in partition structure as valid
763
        Partition.IsValid = 1; // mark data in partition structure as valid
690
        Partition.CurrentWorkingDirectory = Partition.FirstRootDirSector;
764
        Partition.CurrentWorkingDirectory = Partition.FirstRootDirSector;
691
        strcpy(Partition.PathToCwd,"/");       
765
        strcpy(Partition.PathToCwd,"/");
692
        result = 0;
766
        result = 0;
693
        end:
767
        end:
694
        if(result != 0) Fat16_Deinit();
768
        if(result != 0) Fat16_Deinit();
695
        else UART1_PutString("ok");
769
        else UART1_PutString("ok");
696
        return(result);
770
        return(result);
Line 711... Line 785...
711
        u32 i;
785
        u32 i;
Line 712... Line 786...
712
 
786
 
Line 713... Line 787...
713
        if((!Partition.IsValid) || (file == NULL)) return(0);
787
        if((!Partition.IsValid) || (file == NULL)) return(0);
714
 
788
 
715
        for(i = 0; i < BYTES_PER_SECTOR; i++) file->Cache[i] = 0; // clear file cache
789
        for(i = 0; i < BYTES_PER_SECTOR; i++) file->Cache[i] = 0; // clear file cache
716
        if(file->FirstSectorOfCurrCluster == SECTOR_UNDEFINED) return (0); // nothing to do 
790
        if(file->FirstSectorOfCurrCluster == SECTOR_UNDEFINED) return (0); // nothing to do
717
        for(i = 0; i < Partition.SectorsPerCluster; i++)
791
        for(i = 0; i < Partition.SectorsPerCluster; i++)
718
        {
792
        {
719
                file->SectorInCache = file->FirstSectorOfCurrCluster + i;
793
                file->SectorInCache = file->FirstSectorOfCurrCluster + i;
Line 831... Line 905...
831
        // repeat until the end of the fat is  reached and no free cluster has been found so far
905
        // repeat until the end of the fat is  reached and no free cluster has been found so far
832
        }while((fat_sector < Partition.SectorsPerFat) && (!free_cluster));
906
        }while((fat_sector < Partition.SectorsPerFat) && (!free_cluster));
833
        return(free_cluster);
907
        return(free_cluster);
834
}
908
}
Line 835... Line -...
835
 
-
 
836
 
-
 
837
/****************************************************************************************************************************************************/
-
 
838
/* Function:    s16 fseek_(File_t *, s32 *, u8)                                                                                                                                                                                                         */
-
 
839
/*                                                                                                                                                                                                                                                                                                      */
-
 
840
/* Description: This function sets the pointer of the stream relative to the position                                                                                                                           */
-
 
841
/*                              specified by origin (SEEK_SET, SEEK_CUR, SEEK_END)                                                                                                                                                                      */
-
 
842
/* Returnvalue: Is 0 if seek was successful                                                                                                                                                                                                                     */
-
 
843
/****************************************************************************************************************************************************/
-
 
844
s16 fseek_(File_t *file, s32 offset, s16 origin)
-
 
845
{
-
 
846
        s32             fposition       = 0;
-
 
847
        s16     retvalue        = 1;
-
 
848
 
-
 
849
        // the byteindex within a sector 
-
 
850
        u32             byte_index       = 0;                  
-
 
851
        // the  sectorindex within a cluster                                                                    
-
 
852
        u32             sector_index  = 0;
-
 
853
        // the index of the cluster within the clusterchain inside the fat                                                                                                      
-
 
854
        u32     cluster_index = 0;                                                                                                     
-
 
855
 
-
 
856
        // check if the partition is valid      
-
 
857
        if((!Partition.IsValid) || (file == NULL)) return(retvalue);
-
 
858
//......................................................
-
 
859
        if(origin == SEEK_SET)                                                                                                          // Fileposition relative to the beginning of the file.
-
 
860
        {
-
 
861
                fposition = 0;
-
 
862
        }      
-
 
863
//......................................................
-
 
864
        else if(origin == SEEK_END)                                                                                                     // Fileposition relative to the end of the file.
-
 
865
        {
-
 
866
                fposition  = (s32) file->Size;
-
 
867
        }      
-
 
868
//......................................................
-
 
869
        else if(origin == SEEK_CUR)                                                                                                     // Fileposition relative to the current position of the file.
-
 
870
        {
-
 
871
                fposition = (s32)file->Position;
-
 
872
        }      
-
 
873
 
-
 
874
        // calculate the specified fileposition according to the selected mode
-
 
875
        fposition += offset;                                                                                                            // Die Absolute Dateiposition welche durch fseek angesprungen werden soll.
-
 
876
        // is the fileposition within the file?
-
 
877
        if((fposition >= 0) && (fposition <= (s32)file->Size))                                          // Ist die berechnete Dateiposition innerhalb der geöffneten Datei?
-
 
878
        {
-
 
879
                // initialize the filepointer
-
 
880
                file->FirstSectorOfCurrCluster = file->FirstSectorOfFirstCluster;
-
 
881
                file->SectorOfCurrCluster       = 0;
-
 
882
                file->ByteOfCurrSector          = 0;
-
 
883
                file->Position                          = 0;
-
 
884
                // has the specified file at least one valid sector attached?
-
 
885
                if(file->FirstSectorOfCurrCluster == SECTOR_UNDEFINED) return(retvalue);
-
 
886
                // calculate the absolute number of the sector wich contains the fileposition we are looking for
-
 
887
                sector_index = (u32) ((u32)fposition >> 9);
-
 
888
                // calculate the index of the cluster containing the specified sector
-
 
889
                cluster_index = (u32) sector_index / Partition.SectorsPerCluster;      
-
 
890
                // the absolute sectornumber becomes relative to the beginning of the specified cluster
-
 
891
                sector_index = (sector_index % Partition.SectorsPerCluster);           
-
 
892
                // calculate the index of the byteposition the fileposition points to
-
 
893
                byte_index = (u32) fposition % 512;
-
 
894
                // parse the fat till the calculated cluster has been reached
-
 
895
                while(cluster_index--) GetNextCluster(file);
-
 
896
                // set the filepointer to the specified sector and byteposition
-
 
897
                file->SectorOfCurrCluster = (u8) sector_index;
-
 
898
                file->ByteOfCurrSector = (u16) byte_index;
-
 
899
                // the fileposition now equals the filepointer
-
 
900
                file->Position = (u32)fposition;       
-
 
901
                // the specified fileposition has been reached
-
 
902
                retvalue = 0;                                                                                  
-
 
903
        }      
-
 
904
        return(retvalue);
-
 
905
}
-
 
906
 
-
 
907
 
909
 
908
/****************************************************************************************************************************************/
910
/****************************************************************************************************************************************/
909
/* Function:    u16 DeleteClusterChain(File *file);                                                                                                                                                                             */
911
/* Function:    u8 DeleteClusterChain(File *file);                                                                                                                                                                              */
910
/*                                                                                                                                                                                                                                                                              */
912
/*                                                                                                                                                                                                                                                                              */
911
/* Description: This function trances along a cluster chain in the fat and frees all clusters visited.                                                                  */
913
/* Description: This function trances along a cluster chain in the fat and frees all clusters visited.                                                                  */
-
 
914
/*                                                                                                                                                                                                                                                                              */
912
/*                                                                                                                                                                                                                                                                              */
915
/* Returnvalue: returns 1 in success otherwise 0                                                                                                                                                                                */
913
/****************************************************************************************************************************************/
916
/****************************************************************************************************************************************/
914
u8 DeleteClusterChain(u16 StartCluster)
917
u8 DeleteClusterChain(u16 StartCluster)
915
{
918
{
916
        u16 cluster;
919
        u16 cluster;
Line 919... Line 922...
919
        u8 buffer[BYTES_PER_SECTOR];
922
        u8 buffer[BYTES_PER_SECTOR];
920
        u32 sector_in_buffer = 0;
923
        u32 sector_in_buffer = 0;
921
        u8 repeat = 0;
924
        u8 repeat = 0;
Line 922... Line 925...
922
 
925
 
923
        if(!Partition.IsValid) return(0);
926
        if(!Partition.IsValid) return(0);
924
        if(StartCluster == CLUSTER_UNDEFINED) return(0);
927
        if(StartCluster == CLUSTER_UNDEFINED) return(1);
925
        cluster = StartCluster; // init chain trace
928
        cluster = StartCluster; // init chain trace
926
        // if start cluster is no real cluster
929
        // if start cluster is no real cluster
Line 927... Line 930...
927
    if(FAT16_CLUSTER_LAST_MIN <= cluster) return 1;
930
    if(FAT16_CLUSTER_LAST_MIN <= cluster) return(1);
928
 
931
 
929
        // calculate byte offset in the fat for corresponding entry
932
        // calculate byte offset in the fat for corresponding entry
930
        fat_byte_offset = ((u32)cluster)<<1; // two FAT bytes (16 bits) for every cluster
933
        fat_byte_offset = ((u32)cluster)<<1; // two FAT bytes (16 bits) for every cluster
Line 978... Line 981...
978
/*                                                                                                                                                                                                                                                                              */
981
/*                                                                                                                                                                                                                                                                              */
979
/* Description: This function looks in the fat to find the next free cluster and appends it to the file.                                                                */
982
/* Description: This function looks in the fat to find the next free cluster and appends it to the file.                                                                */
980
/*                                                                                                                                                                                                                                                                              */
983
/*                                                                                                                                                                                                                                                                              */
981
/* Returnvalue: The function returns the appened cluster number or CLUSTER_UNDEFINED of no cluster was appended.                                                */
984
/* Returnvalue: The function returns the appened cluster number or CLUSTER_UNDEFINED of no cluster was appended.                                                */
982
/****************************************************************************************************************************************/
985
/****************************************************************************************************************************************/
983
 
-
 
984
u16 AppendCluster(File_t *file)
986
u16 AppendCluster(File_t *file)
985
{
987
{
986
        u16 last_cluster, new_cluster = CLUSTER_UNDEFINED;
988
        u16 last_cluster, new_cluster = CLUSTER_UNDEFINED;
987
        u32 fat_byte_offset, sector, byte;
989
        u32 fat_byte_offset, sector, byte;
988
        Fat16Entry_t * fat;
990
        Fat16Entry_t * fat;
Line -... Line 991...
-
 
991
 
989
 
992
 
Line 990... Line 993...
990
        if((!Partition.IsValid) || (file == NULL)) return(new_cluster);
993
        if((!Partition.IsValid) || (file == NULL)) return(new_cluster);
991
 
994
 
992
        new_cluster = FindNextFreeCluster(file);        // the next free cluster found on the disk.
995
        new_cluster = FindNextFreeCluster(file);        // the next free cluster found on the disk.
-
 
996
        if(new_cluster != CLUSTER_UNDEFINED)
-
 
997
        {       // A free cluster was found and can be added to the end of the file.
-
 
998
                // is there at least one cluster appended to the file?
993
        if(new_cluster != CLUSTER_UNDEFINED)
999
                if(file->FirstSectorOfLastCluster == CLUSTER_UNDEFINED)
-
 
1000
                {
-
 
1001
                        fseek_(file, 0, SEEK_END);                                                                                                      // jump to the end of the file
994
        {       // A free cluster was found and can be added to the end of the file.
1002
                        // remember the first sector of the last cluster
-
 
1003
                        file->FirstSectorOfLastCluster = file->FirstSectorOfCurrCluster;
-
 
1004
                        last_cluster = SectorToFat16Cluster(file->FirstSectorOfCurrCluster);            // determine current file cluster
-
 
1005
                }
-
 
1006
                else
-
 
1007
                {
-
 
1008
                        last_cluster = SectorToFat16Cluster(file->FirstSectorOfLastCluster);            // determine current file cluster
995
                fseek_(file, 0, SEEK_END);                                                                                                      // jump to the end of the file
1009
                }
996
                last_cluster = SectorToFat16Cluster(file->FirstSectorOfCurrCluster);            // determine current file cluster
1010
 
997
                if(last_cluster != CLUSTER_UNDEFINED)
1011
                if(last_cluster != CLUSTER_UNDEFINED)
998
                {
1012
                {
999
                        // update FAT entry of last cluster
1013
                        // update FAT entry of last cluster
Line 1015... Line 1029...
1015
                        if(SD_SUCCESS != SDC_PutSector(file->SectorInCache, file->Cache))               // save the modified sector to the FAT.
1029
                        if(SD_SUCCESS != SDC_PutSector(file->SectorInCache, file->Cache))               // save the modified sector to the FAT.
1016
                        {
1030
                        {
1017
                                Fat16_Deinit();
1031
                                Fat16_Deinit();
1018
                                return(0);
1032
                                return(0);
1019
                        }
1033
                        }
-
 
1034
                        // now the new cluster appended to the fat is the last cluster
-
 
1035
                        file->FirstSectorOfLastCluster = Fat16ClusterToSector(new_cluster);
1020
                }
1036
                }
1021
                else // last cluster of the file is undefined
1037
                else // last cluster of the file is undefined
1022
                {   // then the new cluster must be the first one of the file
1038
                {   // then the new cluster must be the first one of the file
1023
                    // and its cluster number must be set in the direntry
1039
                    // and its cluster number must be set in the direntry
1024
                        DirEntry_t * dir;
1040
                        DirEntry_t * dir;
Line 1030... Line 1046...
1030
                        }
1046
                        }
1031
                        dir = (DirEntry_t *)file->Cache;                                                        // set pointer to directory
1047
                        dir = (DirEntry_t *)file->Cache;                                                        // set pointer to directory
1032
                        dir[file->DirectoryIndex].Res1 = 0;
1048
                        dir[file->DirectoryIndex].Res1 = 0;
1033
                        dir[file->DirectoryIndex].Res2[0] = 0;
1049
                        dir[file->DirectoryIndex].Res2[0] = 0;
1034
                        dir[file->DirectoryIndex].Res2[1] = 0;
1050
                        dir[file->DirectoryIndex].Res2[1] = 0;
1035
                        dir[file->DirectoryIndex].StartCluster = new_cluster;           // update startcluster 
1051
                        dir[file->DirectoryIndex].StartCluster = new_cluster;           // update startcluster
1036
                    dir[file->DirectoryIndex].ModTime   = FileTime(&SystemTime);// set time
1052
                    dir[file->DirectoryIndex].ModTime   = FileTime(&SystemTime);// set time
1037
                        dir[file->DirectoryIndex].ModDate       = FileDate(&SystemTime);// and date of modification
1053
                        dir[file->DirectoryIndex].ModDate       = FileDate(&SystemTime);// and date of modification
1038
                        dir[file->DirectoryIndex].LastAccessDate = dir[file->DirectoryIndex].ModDate;
1054
                        dir[file->DirectoryIndex].LastAccessDate = dir[file->DirectoryIndex].ModDate;
1039
                        dir[file->DirectoryIndex].Size          = 0;
1055
                        dir[file->DirectoryIndex].Size          = 0;
1040
                        // write sector containing the direntry
1056
                        // write sector containing the direntry
1041
                        if(SD_SUCCESS != SDC_PutSector(file->SectorInCache, file->Cache))
1057
                        if(SD_SUCCESS != SDC_PutSector(file->SectorInCache, file->Cache))
1042
                        {
1058
                        {
1043
                                Fat16_Deinit();
1059
                                Fat16_Deinit();
1044
                                return(CLUSTER_UNDEFINED);
1060
                                return(CLUSTER_UNDEFINED);
1045
                        }
1061
                        }
1046
                        // update file info     
1062
                        // update file info
1047
                        file->FirstSectorOfFirstCluster = Fat16ClusterToSector(new_cluster);
1063
                        file->FirstSectorOfFirstCluster = Fat16ClusterToSector(new_cluster);
-
 
1064
                        file->FirstSectorOfLastCluster = file->FirstSectorOfFirstCluster;
1048
                        file->Size = 0;
1065
                        file->Size = 0;
1049
                        file->Position = 0;
1066
                        file->Position = 0;
1050
                }
1067
                }
1051
                // update file pointes
1068
                // update file pointes
1052
                file->FirstSectorOfCurrCluster = Fat16ClusterToSector(new_cluster);
1069
                file->FirstSectorOfCurrCluster = Fat16ClusterToSector(new_cluster);
Line 1076... Line 1093...
1076
 
1093
 
1077
        // if incomming pointers are useless return immediatly
1094
        // if incomming pointers are useless return immediatly
Line 1078... Line 1095...
1078
        if((!Partition.IsValid) || (file == NULL) || (dirname == NULL)) return(direntry_exist);
1095
        if((!Partition.IsValid) || (file == NULL) || (dirname == NULL)) return(direntry_exist);
1079
 
1096
 
1080
        // dir entries can be searched only in filesclusters that have
1097
        // dir entries can be searched only in filesclusters that have
1081
        // a corresponding dir entry with adir-flag set in its attribute
1098
        // a corresponding dir entry with a dir-flag set in its attribute
1082
        // or direct within the root directory area
1099
        // or direct within the root directory area
1083
        file->FirstSectorOfFirstCluster = SECTOR_UNDEFINED;
1100
        file->FirstSectorOfFirstCluster = SECTOR_UNDEFINED;
1084
        // no current directory exist therefore assume searching in the root
1101
        // no current directory exist therefore assume searching in the root
Line 1089... Line 1106...
1089
        }
1106
        }
1090
        // within the root directory area we can read sectors sequentially until the end of this area
1107
        // within the root directory area we can read sectors sequentially until the end of this area
1091
        else if((Partition.FirstRootDirSector <= file->DirectorySector) && (file->DirectorySector < Partition.FirstDataSector))
1108
        else if((Partition.FirstRootDirSector <= file->DirectorySector) && (file->DirectorySector < Partition.FirstDataSector))
1092
        {
1109
        {
1093
                max_dir_sector = (Partition.MaxRootEntries * DIRENTRY_SIZE)/BYTES_PER_SECTOR;
1110
                max_dir_sector = (Partition.MaxRootEntries * DIRENTRY_SIZE)/BYTES_PER_SECTOR;
-
 
1111
                file->FirstSectorOfFirstCluster = Partition.FirstRootDirSector;
1094
        }
1112
        }
1095
        // within the data clusters we can read sectors sequentially only within the cluster
1113
        // within the data clusters we can read sectors sequentially only within the cluster
1096
        else if((Partition.FirstDataSector <= file->DirectorySector) && (file->DirectorySector <= Partition.LastDataSector))
1114
        else if((Partition.FirstDataSector <= file->DirectorySector) && (file->DirectorySector <= Partition.LastDataSector))
1097
        {
1115
        {
1098
                max_dir_sector = Partition.SectorsPerCluster;                           // limit max secters before next cluster
1116
                max_dir_sector = Partition.SectorsPerCluster;                           // limit max sectors before next cluster
1099
        }
1117
        }
1100
        else return (direntry_exist); // bad sector range for directory sector of the file
1118
        else return (direntry_exist); // bad sector range for directory sector of the file
1101
        // if search area is not defined yet
1119
        // if search area is not defined yet, i.e. not in the root directory area
1102
        if(file->FirstSectorOfFirstCluster == SECTOR_UNDEFINED)
1120
        if(file->FirstSectorOfFirstCluster == SECTOR_UNDEFINED)
1103
        {
1121
        {
1104
                // check if the directory entry of current file is existent and has the dir-flag set
1122
                // check if the directory entry of current file is existent and has the dir-flag set
1105
                file->SectorInCache = file->DirectorySector;                            // update the sector number of file cache.
1123
                file->SectorInCache = file->DirectorySector;                            // update the sector number of file cache.
1106
                if(SD_SUCCESS != SDC_GetSector(file->SectorInCache, file->Cache))// read in the sector.
1124
                if(SD_SUCCESS != SDC_GetSector(file->SectorInCache, file->Cache))// read in the sector.
Line 1112... Line 1130...
1112
                switch((u8)dir[file->DirectoryIndex].Name[0])                           // check if current directory exist
1130
                switch((u8)dir[file->DirectoryIndex].Name[0])                           // check if current directory exist
1113
                {
1131
                {
1114
                        case SLOT_EMPTY:
1132
                        case SLOT_EMPTY:
1115
                        case SLOT_DELETED:
1133
                        case SLOT_DELETED:
1116
                                // the directrory pointer of this file points to a deleted or not existen directory
1134
                                // the directrory pointer of this file points to a deleted or not existen directory
1117
                                // therefore no file or subdirectory can be created
1135
                                // therefore no file or subdirectory exist here
1118
                                return (direntry_exist);
1136
                                return (direntry_exist);
1119
                                break;
1137
                                break;
1120
                        default:        // and is a real directory
1138
                        default:        // and is a real directory
1121
                                if((dir[file->DirectoryIndex].Attribute & ATTR_SUBDIRECTORY) != ATTR_SUBDIRECTORY)
1139
                                if((dir[file->DirectoryIndex].Attribute & ATTR_SUBDIRECTORY) != ATTR_SUBDIRECTORY)
1122
                                {       // current file is not a directory therefore no file or subdirectory can be created here
1140
                                {       // current file is not a directory therefore no file or subdirectory can be created here
Line 1124... Line 1142...
1124
                                }
1142
                                }
1125
                                break;
1143
                                break;
1126
                }
1144
                }
1127
                file->FirstSectorOfFirstCluster = Fat16ClusterToSector(dir[file->DirectoryIndex].StartCluster);
1145
                file->FirstSectorOfFirstCluster = Fat16ClusterToSector(dir[file->DirectoryIndex].StartCluster);
1128
        }
1146
        }
1129
 
-
 
1130
        // update current file data area position to start of first cluster
1147
        // update current file data area position to start of first cluster
1131
        file->FirstSectorOfCurrCluster  = file->FirstSectorOfFirstCluster;
1148
        file->FirstSectorOfCurrCluster  = file->FirstSectorOfFirstCluster;
1132
        file->SectorOfCurrCluster               = 0;
1149
        file->SectorOfCurrCluster               = 0;
1133
        file->ByteOfCurrSector                  = 0;
1150
        file->ByteOfCurrSector                  = 0;
Line 1222... Line 1239...
1222
        }
1239
        }
1223
        // within the root directory area we can read sectors sequentially until the end of this area
1240
        // within the root directory area we can read sectors sequentially until the end of this area
1224
        else if((Partition.FirstRootDirSector <= file->DirectorySector) && (file->DirectorySector < Partition.FirstDataSector))
1241
        else if((Partition.FirstRootDirSector <= file->DirectorySector) && (file->DirectorySector < Partition.FirstDataSector))
1225
        {
1242
        {
1226
                max_dir_sector = (Partition.MaxRootEntries * DIRENTRY_SIZE)/BYTES_PER_SECTOR;
1243
                max_dir_sector = (Partition.MaxRootEntries * DIRENTRY_SIZE)/BYTES_PER_SECTOR;
-
 
1244
                dircluster = 0;
-
 
1245
                file->FirstSectorOfFirstCluster = Partition.FirstRootDirSector;
1227
        }
1246
        }
1228
        // within the data clusters we can read sectors sequentially only within the cluster
1247
        // within the data clusters we can read sectors sequentially only within the cluster
1229
        else if((Partition.FirstDataSector <= file->DirectorySector) && (file->DirectorySector <= Partition.LastDataSector))
1248
        else if((Partition.FirstDataSector <= file->DirectorySector) && (file->DirectorySector <= Partition.LastDataSector))
1230
        {
1249
        {
1231
                max_dir_sector = Partition.SectorsPerCluster;
1250
                max_dir_sector = Partition.SectorsPerCluster;
-
 
1251
                file->FirstSectorOfFirstCluster = Partition.CurrentWorkingDirectory;
1232
        }
1252
        }
1233
        else return (retvalue); // bad sector range for directory sector of the file
1253
        else return (retvalue); // bad sector range for directory sector of the file
1234
        // if search area is not defined yet
1254
        // if search area is not defined yet
1235
        if(file->FirstSectorOfFirstCluster == SECTOR_UNDEFINED)
1255
        if(file->FirstSectorOfFirstCluster == SECTOR_UNDEFINED)
1236
        {
1256
        {
Line 1259... Line 1279...
1259
                file->FirstSectorOfFirstCluster = Fat16ClusterToSector(dircluster);
1279
                file->FirstSectorOfFirstCluster = Fat16ClusterToSector(dircluster);
1260
        }
1280
        }
Line 1261... Line 1281...
1261
 
1281
 
1262
        // if the new direntry is a subdirectory
1282
        // if the new direntry is a subdirectory
1263
        if((attrib & ATTR_SUBDIRECTORY) == ATTR_SUBDIRECTORY)
1283
        if((attrib & ATTR_SUBDIRECTORY) == ATTR_SUBDIRECTORY)
1264
        {       // get a free clutser for its content
1284
        {       // get a free cluster for its content
1265
                subdircluster = FindNextFreeCluster(file);      // get the next free cluster on the disk and mark it as used.
1285
                subdircluster = FindNextFreeCluster(file);      // get the next free cluster on the disk and mark it as used.
1266
        }
1286
        }
1267
        else // a normal file
1287
        else // a normal file
1268
        {       // has no data cluster after creation
1288
        {       // has no data cluster after creation
Line 1275... Line 1295...
1275
        {
1295
        {
1276
                dir_sector = 0; // reset sector counter within a new cluster
1296
                dir_sector = 0; // reset sector counter within a new cluster
1277
                do // loop over all sectors of a cluster or all sectors of the root directory
1297
                do // loop over all sectors of a cluster or all sectors of the root directory
1278
                {
1298
                {
1279
                        curr_sector = file->FirstSectorOfCurrCluster + dir_sector;      // calculate sector number
1299
                        curr_sector = file->FirstSectorOfCurrCluster + dir_sector;      // calculate sector number
1280
                        file->SectorInCache = curr_sector;                                                      // upate the sector number of file cache.
1300
                        file->SectorInCache = curr_sector;                                                      // update the sector number of file cache.
1281
                        if(SD_SUCCESS != SDC_GetSector(file->SectorInCache, file->Cache))// read in the sector.
1301
                        if(SD_SUCCESS != SDC_GetSector(file->SectorInCache, file->Cache))// read in the sector.
1282
                        {
1302
                        {
1283
                                Fat16_Deinit();
1303
                                Fat16_Deinit();
1284
                                return(0);
1304
                                return(0);
1285
                        }
1305
                        }
Line 1368... Line 1388...
1368
 
1388
 
1369
        return(retvalue);       // return 1 if file has been created otherwise return 0.
1389
        return(retvalue);       // return 1 if file has been created otherwise return 0.
Line 1370... Line 1390...
1370
}
1390
}
-
 
1391
 
-
 
1392
/********************************************************************************************************************************************/
-
 
1393
/*      Function:               u8 DeleteDirectoryEntry(File_t *file)                                                                                                                                                                   */
-
 
1394
/*      Description:    This function deletes the directoryentry of the file to be deleted from the filesystem                                                                  */
-
 
1395
/*                                                                                                                                                                                                                                      */
-
 
1396
/*                                                                                                                                                                                                                                                                                      */
-
 
1397
/*      Returnvalue:    1 on succes and 0 on error                                                                                                                                                                                              */
-
 
1398
/********************************************************************************************************************************************/
-
 
1399
u8 DeleteDirectoryEntry(File_t *file)
-
 
1400
{
-
 
1401
        DirEntry_t *DirectoryEntry = NULL;
-
 
1402
        u8 retval = 0;
-
 
1403
 
-
 
1404
        if((!Partition.IsValid) || (file == NULL)) return (retval);
-
 
1405
 
-
 
1406
        // try to  read the sector containing the directoryentry of the file to be deleted 
-
 
1407
        if(SD_SUCCESS != SDC_GetSector((u32) file->DirectorySector,file->Cache)) return(retval);
-
 
1408
        // get access to the elements of the directoryentry
-
 
1409
        DirectoryEntry = (DirEntry_t *)file->Cache;
-
 
1410
        // delete the directoryentry
-
 
1411
        DirectoryEntry[file->DirectoryIndex].Name[0] = SLOT_DELETED;
-
 
1412
        DirectoryEntry[file->DirectoryIndex].Attribute = 0;
-
 
1413
        DirectoryEntry[file->DirectoryIndex].Size = 0;
-
 
1414
        // the file has been deleted from the directory, save the modified sector back to the filesystem 
-
 
1415
        if(SD_SUCCESS == SDC_PutSector((u32) file->DirectorySector,file->Cache)) retval = 1;
-
 
1416
        return(retval);
-
 
1417
}
1371
 
1418
 
1372
/********************************************************************************************************************************************/
1419
/********************************************************************************************************************************************/
1373
/*      Function:               FileExist(const s8* filename, u8 attribfilter, u8 attribmask, File_t *file);                                                                                    */
1420
/*      Function:               FileExist(const s8* filename, u8 attribfilter, u8 attribmask, File_t *file);                                                                                    */
1374
/*                                                                                                                                                                                                                                                                                      */
1421
/*                                                                                                                                                                                                                                                                                      */
1375
/*      Description:    This function looks for the specified file including its subdirectories beginning                                                                               */
-
 
1376
/*                                      in the rootdirectory of the drive. If the file is found the Filepointer properties are                                                                  */
1422
/*      Description:    This function looks for the specified file including its subdirectories.                                                                                                */
1377
/*                                      updated.                                                                                                                                                                                                                                */
1423
/*                  If the file is found the Filepointer properties are updated.                                                                                                                        */
1378
/*                                                                                                                                                                                                                                                                                      */
1424
/*                                                                                                                                                                                                                                                                                      */
1379
/*      Returnvalue:    1 if file is found else 0.                                                                                                                                                                                              */
1425
/*      Returnvalue:    1 if file is found else 0.                                                                                                                                                                                              */
1380
/********************************************************************************************************************************************/
1426
/********************************************************************************************************************************************/
Line 1387... Line 1433...
1387
 
1433
 
1388
        // if incomming pointers are useless return immediatly
1434
        // if incomming pointers are useless return immediatly
Line 1389... Line 1435...
1389
        if ((filename == NULL) || (file == NULL) || (!Partition.IsValid)) return 0;
1435
        if ((filename == NULL) || (file == NULL) || (!Partition.IsValid)) return 0;
1390
 
1436
 
1391
        // trace along the filepath
-
 
1392
        path = (s8*)filename;                                                           // start a the beginning of the filename string
1437
        // trace along the filepath
1393
        file->DirectorySector = 0;                                                              // start at RootDirectory with file search
1438
        path = (s8*)filename;                                                           // start at the beginning of the filename string
-
 
1439
        file->DirectoryIndex = 0;
-
 
1440
        if(path[0] == '/') // if a path begins  with a '/' the search starts at RootDirectory with file search
-
 
1441
        {
1394
        file->DirectoryIndex = 0;
1442
                file->DirectorySector = Partition.FirstRootDirSector;   // start at RootDirectory with file search      
1395
        /* if a path begins with a '/' at index 0 the search starts at the rootdirectory otherwise we will start relative to the cwd */
1443
        }
1396
        if(path[0] != '/')
-
 
1397
        {
-
 
1398
                /* is the current working directory the rootdirectory? */
-
 
1399
                if(Partition.CurrentWorkingDirectory == Partition.FirstRootDirSector) file->DirectorySector = 0;
1444
        else // if a path begins not with a '/' the search starts relative to the CWD
1400
                /* otherwise we are working in an subdirectory */
1445
        {
1401
                else file->DirectorySector = Partition.CurrentWorkingDirectory;
1446
                file->DirectorySector = Partition.CurrentWorkingDirectory;
1402
        }
1447
        }
1403
        // as long as the file was not found and the remaining path is not empty
1448
        // as long as the file was not found and the remaining path is not empty
1404
        while((*path != 0) && !file_exist)
1449
        while((*path != 0) && !file_exist)
1405
        {       // separate dirname and subpath from filepath string
1450
        {       // separate dirname and subpath from filepath string
1406
                subpath = SeperateDirName(path, dirname);
1451
                subpath = SeperateFormatedDirName(path, dirname);
1407
                if(subpath != NULL)
1452
                if(subpath != NULL)
1408
                {
1453
                {
1409
                        if(*subpath == 0)
1454
                        if(*subpath == 0)
Line 1454... Line 1499...
1454
        s8 *subpath = 0;
1499
        s8 *subpath = 0;
1455
        u8 af, am, file_created = 0;
1500
        u8 af, am, file_created = 0;
1456
        s8 dirname[12];
1501
        s8 dirname[12];
Line 1457... Line 1502...
1457
 
1502
 
1458
        // if incomming pointers are useless return immediatly
1503
        // if incomming pointers are useless return immediatly
Line 1459... Line 1504...
1459
        if ((filename == NULL) || (file == NULL) || (!Partition.IsValid)) return 0;
1504
        if ((filename == NULL) || (file == NULL) || (!Partition.IsValid)) return(0);
-
 
1505
 
-
 
1506
        // trace along the filepath
1460
 
1507
        path = (s8*)filename;
-
 
1508
 
1461
        // trace along the filepath
1509
        if(path[0] == '/') // if a path begins  with a '/' the search starts at RootDirectory with file search
-
 
1510
        {
-
 
1511
                file->DirectorySector = Partition.FirstRootDirSector;   // start at RootDirectory with file search      
-
 
1512
        }
-
 
1513
        else // if a path begins not with a '/' the search starts relative to the CWD
-
 
1514
        {
1462
        path = (s8*)filename;                                                                   // start a the beginning of the filename string
1515
                file->DirectorySector = Partition.CurrentWorkingDirectory;
-
 
1516
        }
1463
        file->DirectorySector = 0;                                                              // start at RootDirectory with file search
1517
        file->DirectoryIndex = 0;
1464
        file->DirectoryIndex = 0;
1518
 
1465
        // as long as the file was not created and the remaining file path is not empty
1519
        // as long as the file was not created and the remaining file path is not empty
1466
        while((*path != 0) && !file_created)
1520
        while((*path != 0) && !file_created)
1467
        {   // separate dirname and subpath from filepath string
1521
        {   // separate dirname and subpath from filepath string
1468
                subpath = SeperateDirName(path, dirname);
1522
                subpath = SeperateFormatedDirName(path, dirname);
1469
                if(subpath != NULL)
1523
                if(subpath != NULL)
1470
                {
1524
                {
1471
                        if(*subpath == 0)
1525
                        if(*subpath == 0)
1472
                        {       // empty subpath indicates last element of dir chain
1526
                        {       // empty subpath indicates last element of dir chain
1473
                                af = ATTR_NONE;
1527
                                af = ATTR_NONE;
1474
                                am = ATTR_SUBDIRECTORY|ATTR_VOLUMELABEL;  // any file that is no subdir or volume label
1528
                                am = ATTR_SUBDIRECTORY|ATTR_VOLUMELABEL;  // any file that is no subdir or volume label
1475
                        }
1529
                        }
1476
                        else  // it must be a subdirectory and no volume label
1530
                        else  // it must be a subdirectory but no volume label
1477
                        {
1531
                        {
1478
                                af = ATTR_SUBDIRECTORY;
1532
                                af = ATTR_SUBDIRECTORY;
1479
                                am = ATTR_SUBDIRECTORY|ATTR_VOLUMELABEL;
1533
                                am = ATTR_SUBDIRECTORY|ATTR_VOLUMELABEL;
Line 1483... Line 1537...
1483
                                if(*subpath == 0) af = attrib; // if last element in dir chain take the given attribute
1537
                                if(*subpath == 0) af = attrib; // if last element in dir chain take the given attribute
1484
                                if(!CreateDirectoryEntry(dirname, af, file))
1538
                                if(!CreateDirectoryEntry(dirname, af, file))
1485
                                {       // could not be created
1539
                                {       // could not be created
1486
                                        return(file_created);
1540
                                        return(file_created);
1487
                                }
1541
                                }
1488
                                else if (*subpath == 0) file_created = 1; // last element of path chain was created
1542
                                else if(*subpath == 0) file_created = 1; // last element of path chain was created
1489
                        }
1543
                        }
1490
                }
1544
                }
1491
                else // error seperating the subpath
1545
                else // error seperating the subpath
1492
                {
1546
                {
1493
                        return file_created; // bad subdir format
1547
                        return file_created; // bad subdir format
1494
                }
1548
                }
1495
                path = subpath;
1549
                path = subpath;
1496
                subpath = 0;
1550
                subpath = NULL;
1497
        }
1551
        }
1498
        return (file_created);
1552
        return (file_created);
1499
}
1553
}
Line 1500... Line 1554...
1500
 
1554
 
-
 
1555
 
-
 
1556
/********************************************************************************************************************************************/
-
 
1557
/*      Function:               void Slashing_Path(s8*)                                                                                                                                                                                                 */
-
 
1558
/*                                                                                                                                                                                                                                                                                      */
-
 
1559
/*      Description:    This function replaces all \ by / in the string pointed to by the argument                                                                              */
-
 
1560
/*                                                                                                                                                                                                                                      */
-
 
1561
/*                                                                                                                                                                                                                                                                                      */
-
 
1562
/*      Returnvalue:                                                                                                                                                                                                                                                    */
-
 
1563
/********************************************************************************************************************************************/
-
 
1564
void Slashing_Path(s8* path)
-
 
1565
{
-
 
1566
        s8 *cptr = path;
-
 
1567
        while(*cptr != 0 )
-
 
1568
        {
-
 
1569
                if(*cptr == '\\') *cptr = '/'; // replace \ by /
-
 
1570
                cptr++;
-
 
1571
        }
-
 
1572
}
1501
 
1573
 
1502
/********************************************************************************************************************************************/
1574
/********************************************************************************************************************************************/
1503
/*      Function:               File_t * fopen_(s8* filename, s8 mode);                                                                                                                                                                 */
1575
/*      Function:               File_t * fopen_(s8* filename, s8 mode);                                                                                                                                                                 */
1504
/*                                                                                                                                                                                                                                                                                      */
1576
/*                                                                                                                                                                                                                                                                                      */
1505
/*      Description:    This function looks for the specified file in the rootdirectory of the drive. If the file is found the number of the    */
1577
/*      Description:    This function looks for the specified file in the rootdirectory of the drive. If the file is found the number of the    */
1506
/*                                      corrosponding filepointer is returned. Only modes 'r' (reading) and 'a' append are implemented yet.                                             */
1578
/*                                      corrosponding filepointer is returned. Only modes 'r' (reading), 'w' (writing) and 'a' (append) are implemented yet.    */
1507
/*                                                                                                                                                                                                                                                                                      */
1579
/*                                                                                                                                                                                                                                                                                      */
1508
/*      Returnvalue:    The filepointer to the file or 0 if faild.                                                                                                                                                              */
1580
/*      Returnvalue:    The filepointer to the file or 0 if faild.                                                                                                                                                              */
1509
/********************************************************************************************************************************************/
1581
/********************************************************************************************************************************************/
1510
File_t * fopen_(s8 * const filename, const s8 mode)
1582
File_t * fopen_(s8* const filename, const s8 mode)
1511
{
1583
{
Line 1512... Line 1584...
1512
        File_t *file    = 0;
1584
        File_t *file    = 0;
Line 1518... Line 1590...
1518
        file = LockFilePointer();
1590
        file = LockFilePointer();
1519
        // if no unused file pointer was found return 0
1591
        // if no unused file pointer was found return 0
1520
        if(file == NULL) return(file);
1592
        if(file == NULL) return(file);
Line 1521... Line 1593...
1521
 
1593
 
1522
        // now we have found a free filepointer and claimed it
-
 
1523
        // so let initiate its property values
-
 
1524
        file->FirstSectorOfFirstCluster = SECTOR_UNDEFINED;             // Sectorpointer to the first sector of the first datacluster of the file.
-
 
1525
        file->FirstSectorOfCurrCluster  = SECTOR_UNDEFINED;             // Pointer to the cluster which is edited at the moment.
-
 
1526
        file->SectorOfCurrCluster               = 0;            // The sector which is edited at the moment (cluster_pointer + sector_index).
-
 
1527
        file->ByteOfCurrSector                  = 0;            // The bytelocation within the current sector (cluster_pointer + sector_index + byte_index).
1594
        // now we have found a free filepointer and claimed it
1528
        file->Mode                                              = mode;         // mode of fileoperation (read,write)
-
 
1529
        file->Size                                              = 0;            // the size of the opened file in bytes.
-
 
1530
        file->Position                                  = 0;            // pointer to a byte within the file 0 < fileposition < filesize
-
 
1531
        file->SectorInCache                             = SECTOR_UNDEFINED;             // the last sector read, wich is still in the sectorbuffer.
-
 
1532
        file->DirectorySector                   = SECTOR_UNDEFINED;             // the sectorposition where the directoryentry has been made.
-
 
1533
        file->DirectoryIndex                    = 0;            // the index to the directoryentry within the specified sector.
1595
        file->Mode                                              = mode;         // mode of fileoperation (read,write)
Line 1534... Line 1596...
1534
        file->Attribute                                 = 0;            // the attribute of the file opened.
1596
        file->Attribute                                 = 0;            // the attribute of the file opened.
-
 
1597
 
1535
 
1598
        // bring the path into the correct syntax
1536
        // bring the path into the correct syntax 
-
 
1537
        cptr = filename;
-
 
1538
        // search the whole string 
-
 
1539
        while(*cptr != 0)
-
 
1540
        {
-
 
1541
                // replace all '\' by '/'
-
 
1542
                if(*cptr == '\\') *cptr = '/';
1599
        Slashing_Path(filename);
1543
                cptr++;
1600
        cptr = filename;
1544
        }
1601
 
1545
        // check if a real file (no directory) to the given filename exist
1602
        // check if a real file (no directory) to the given filename exist
1546
        if(FileExist(filename, ATTR_NONE, ATTR_SUBDIRECTORY|ATTR_VOLUMELABEL, file))
1603
        if(FileExist(filename, ATTR_NONE, ATTR_SUBDIRECTORY|ATTR_VOLUMELABEL, file))
1547
        {  // file exist
1604
        {  // file exist
Line 1578... Line 1635...
1578
                                        }
1635
                                        }
1579
                                        dir = (DirEntry_t *)file->Cache;                                                                // set pointer to directory
1636
                                        dir = (DirEntry_t *)file->Cache;                                                                // set pointer to directory
1580
                                    dir[file->DirectoryIndex].ModTime   = FileTime(&SystemTime);        // set modification time
1637
                                    dir[file->DirectoryIndex].ModTime   = FileTime(&SystemTime);        // set modification time
1581
                                        dir[file->DirectoryIndex].ModDate       = FileDate(&SystemTime);        // set modification date
1638
                                        dir[file->DirectoryIndex].ModDate       = FileDate(&SystemTime);        // set modification date
1582
                                        dir[file->DirectoryIndex].LastAccessDate = dir[file->DirectoryIndex].ModDate;
1639
                                        dir[file->DirectoryIndex].LastAccessDate = dir[file->DirectoryIndex].ModDate;
1583
                                        dir[file->DirectoryIndex].StartCluster = CLUSTER_UNDEFINED;             // update startcluster 
1640
                                        dir[file->DirectoryIndex].StartCluster = CLUSTER_UNDEFINED;             // update startcluster
1584
                                        dir[file->DirectoryIndex].Size          = 0;
1641
                                        dir[file->DirectoryIndex].Size          = 0;
1585
                                        // write sector containing the direntry
1642
                                        // write sector containing the direntry
1586
                                        if(SD_SUCCESS != SDC_PutSector(file->SectorInCache, file->Cache))
1643
                                        if(SD_SUCCESS != SDC_PutSector(file->SectorInCache, file->Cache))
1587
                                        {
1644
                                        {
1588
                                                Fat16_Deinit();
1645
                                                Fat16_Deinit();
Line 1617... Line 1674...
1617
                                // try to create the file
1674
                                // try to create the file
1618
                                if(!FileCreate(filename, ATTR_ARCHIVE, file))
1675
                                if(!FileCreate(filename, ATTR_ARCHIVE, file))
1619
                                { // if it could not be created
1676
                                { // if it could not be created
1620
                                        fclose_(file);
1677
                                        fclose_(file);
1621
                                        file = NULL;
1678
                                        file = NULL;
1622
                                }
1679
                                }
1623
                                break;
1680
                                break;
1624
                        case 'r': // else opened for 'r'
1681
                        case 'r': // else opened for 'r'
1625
                        default:  // if unsupported mode
1682
                        default:  // if unsupported mode
1626
                                fclose_(file);
1683
                                fclose_(file);
1627
                                file = NULL;
1684
                                file = NULL;
Line 1634... Line 1691...
1634
        file = NULL;
1691
        file = NULL;
1635
        return(file);
1692
        return(file);
1636
}
1693
}
Line 1637... Line 1694...
1637
 
1694
 
-
 
1695
/****************************************************************************************************************************************************/
-
 
1696
/* Function:    s16 fseek_(File_t *, s32 *, u8)                                                                                                                                                                                                         */
-
 
1697
/*                                                                                                                                                                                                                                                                                                      */
-
 
1698
/* Description: This function sets the pointer of the stream relative to the position                                                                                                                           */
-
 
1699
/*                              specified by origin (SEEK_SET, SEEK_CUR, SEEK_END)                                                                                                                                                                      */
-
 
1700
/* Returnvalue: Is 0 if seek was successful                                                                                                                                                                                                                     */
-
 
1701
/****************************************************************************************************************************************************/
-
 
1702
s16 fseek_(File_t *file, s32 offset, s16 origin)
-
 
1703
{
-
 
1704
        s32             fposition       = 0;
-
 
1705
        s16     retvalue        = 1;
-
 
1706
        u32             byte_index       = 0;   // the byteindex within a sector
-
 
1707
        u32             sector_index  = 0;      // the  sectorindex within a cluster
-
 
1708
        u32     cluster_index = 0;      // the index of the cluster within the clusterchain inside the fat
-
 
1709
 
-
 
1710
        // check if the partition is valid
-
 
1711
        if((!Partition.IsValid) || (file == NULL)) return(retvalue);
-
 
1712
        switch(origin)
-
 
1713
        {
-
 
1714
                case SEEK_SET:                          // Fileposition relative to the beginning of the file.
-
 
1715
                        fposition = 0;
-
 
1716
                        break;
-
 
1717
                case SEEK_END:                          // Fileposition relative to the end of the file.
-
 
1718
                        fposition = (s32)file->Size;
-
 
1719
                        break;
-
 
1720
                case SEEK_CUR:                          // Fileposition relative to the current position of the file.
-
 
1721
                default:
-
 
1722
                        fposition = file->Position;
-
 
1723
                        break;
-
 
1724
        }
-
 
1725
 
-
 
1726
        // calculate the specified fileposition according to the selected mode
-
 
1727
        fposition += offset;
-
 
1728
        // is the fileposition within the file?
-
 
1729
        if((fposition >= 0) && (fposition <= (s32)file->Size))
-
 
1730
        {
-
 
1731
                // initialize the filepointer to start of the file
-
 
1732
                file->FirstSectorOfCurrCluster = file->FirstSectorOfFirstCluster;
-
 
1733
                file->SectorOfCurrCluster       = 0;
-
 
1734
                file->ByteOfCurrSector          = 0;
-
 
1735
                file->Position                          = 0;
-
 
1736
                // has the specified file at least one valid sector attached?
-
 
1737
                if(file->FirstSectorOfCurrCluster == SECTOR_UNDEFINED) return(retvalue);
-
 
1738
                // calculate the absolute number of the sector wich contains the fileposition we are looking for
-
 
1739
                sector_index = (u32) ((u32)fposition >> 9);      // 512 bytes per sector
-
 
1740
                // calculate the index of the cluster containing the specified sector
-
 
1741
                cluster_index = (u32) sector_index / Partition.SectorsPerCluster;
-
 
1742
                // the absolute sectornumber becomes relative to the beginning of the specified cluster
-
 
1743
                sector_index = (sector_index % Partition.SectorsPerCluster);
-
 
1744
                // calculate the index of the byteposition the fileposition points to
-
 
1745
                byte_index = (u32) fposition % 512;
-
 
1746
                // parse the fat till the calculated cluster has been reached
-
 
1747
                while(cluster_index--) GetNextCluster(file);
-
 
1748
                // set the filepointer to the specified sector and byteposition
-
 
1749
                file->SectorOfCurrCluster = (u8) sector_index;
-
 
1750
                file->ByteOfCurrSector = (u16) byte_index;
-
 
1751
                // the fileposition now equals the filepointer
-
 
1752
                file->Position = (u32)fposition;
-
 
1753
                // the specified fileposition has been reached
-
 
1754
                retvalue = 0;
-
 
1755
        }
-
 
1756
        return(retvalue);
-
 
1757
}
-
 
1758
 
1638
/****************************************************************************************************************************************************/
1759
/****************************************************************************************************************************************************/
1639
/* Function:    fflush_(File *);                                                                                                                                                                                                                                        */
1760
/* Function:    fflush_(File *);                                                                                                                                                                                                                                        */
1640
/*                                                                                                                                                                                                                                                                                                      */
1761
/*                                                                                                                                                                                                                                                                                                      */
1641
/* Description: This function writes the data already in the buffer but not yet written to the file.                                                                                            */
1762
/* Description: This function writes the data already in the buffer but not yet written to the file.                                                                                            */
1642
/*                                                                                                                                                                                                                                                                                                      */
1763
/*                                                                                                                                                                                                                                                                                                      */
Line 1687... Line 1808...
1687
 
1808
 
1688
        }
1809
        }
1689
        return(0);
1810
        return(0);
Line 1690... Line -...
1690
}
-
 
1691
 
-
 
1692
/****************************************************************************************************************************************/
-
 
1693
/*      Function:               fclose_(File *file);                                                                                                                                                                                            */
-
 
1694
/*                                                                                                                                                                                                                                                                              */
-
 
1695
/*      Description:    This function closes the open file by writing the remaining data                                                                                                        */
-
 
1696
/*                                      from the buffer to the device and entering the filesize in the directory entry.                                                                         */
-
 
1697
/*                                                                                                                                                                                                                                                                              */
-
 
1698
/*      Returnvalue:    0 on success EOF on error                                                                                                                                                                                       */
-
 
1699
/****************************************************************************************************************************************/
-
 
1700
s16 fclose_(File_t *file)
-
 
1701
{
-
 
1702
        s16 returnvalue = EOF;
-
 
1703
 
-
 
1704
        if(file == NULL) return(returnvalue);
-
 
1705
        returnvalue = fflush_(file);
-
 
1706
        UnlockFilePointer(file);
-
 
1707
        return(returnvalue);
-
 
1708
}
1811
}
1709
 
1812
 
1710
/********************************************************************************************************************************************/
1813
/********************************************************************************************************************************************/
1711
/*      Function:               fgetc_(File *file);                                                                                                                                                                                                             */
1814
/*      Function:               fgetc_(File *file);                                                                                                                                                                                                             */
1712
/*                                                                                                                                                                                                                                                                                      */
1815
/*                                                                                                                                                                                                                                                                                      */
Line 1779... Line 1882...
1779
                case 'w':
1882
                case 'w':
1780
                case 'a':
1883
                case 'a':
1781
                        // If file position equals to file size, then the end of file has been reached.
1884
                        // If file position equals to file size, then the end of file has been reached.
1782
                        // In this case it has to be checked that the ByteOfCurrSector is BYTES_PER_SECTOR
1885
                        // In this case it has to be checked that the ByteOfCurrSector is BYTES_PER_SECTOR
1783
                        // and a new cluster should be appended.
1886
                        // and a new cluster should be appended.
1784
                        // If the first sector of first cluster is unvalid, then the file claims no data clusters 
1887
                        // If the first sector of first cluster is unvalid, then the file claims no data clusters
1785
                        // and size should be zero, therefore append a new Cluster too.
1888
                        // and size should be zero, therefore append a new Cluster too.
1786
                        if(((file->Position >= file->Size) && (file->ByteOfCurrSector >= BYTES_PER_SECTOR)) || (file->FirstSectorOfFirstCluster == SECTOR_UNDEFINED))
1889
                        if(((file->Position >= file->Size) && (file->ByteOfCurrSector >= BYTES_PER_SECTOR)) || (file->FirstSectorOfFirstCluster == SECTOR_UNDEFINED))
1787
                        {
1890
                        {
1788
                                if(CLUSTER_UNDEFINED == AppendCluster(file)) return(EOF);
1891
                                if(CLUSTER_UNDEFINED == AppendCluster(file)) return(EOF);
1789
                        }
1892
                        }
1790
               
1893
 
1791
                        curr_sector  = file->FirstSectorOfCurrCluster;
1894
                        curr_sector  = file->FirstSectorOfCurrCluster;
1792
                        curr_sector += file->SectorOfCurrCluster;
1895
                        curr_sector += file->SectorOfCurrCluster;
1793
                        if(file->SectorInCache != curr_sector)
1896
                        if(file->SectorInCache != curr_sector)
1794
                        {
1897
                        {
1795
                                file->SectorInCache = curr_sector;
1898
                                file->SectorInCache = curr_sector;
Line 1797... Line 1900...
1797
                                {
1900
                                {
1798
                                        Fat16_Deinit();
1901
                                        Fat16_Deinit();
1799
                                        return(EOF);
1902
                                        return(EOF);
1800
                                }
1903
                                }
1801
                        }
1904
                        }
1802
               
1905
 
1803
                        file->Cache[file->ByteOfCurrSector] = (u8)c;            // write databyte into the buffer. The byte will be written to the device at once
1906
                        file->Cache[file->ByteOfCurrSector] = (u8)c;            // write databyte into the buffer. The byte will be written to the device at once
1804
                        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.
1907
                        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.
1805
                        file->Position++;                                                                       // the actual positon within the file.
1908
                        file->Position++;                                                                       // the actual positon within the file.
1806
                        file->ByteOfCurrSector++;                                                       // goto next byte in sector
1909
                        file->ByteOfCurrSector++;                                                       // goto next byte in sector
1807
                        if(file->ByteOfCurrSector >= BYTES_PER_SECTOR)          // if the end of this sector is reached yet
1910
                        if(file->ByteOfCurrSector >= BYTES_PER_SECTOR)          // if the end of this sector is reached yet
1808
                        {       // save the sector to the sd-card
1911
                        {       // save the sector to the sd-card
1809
       
1912
 
1810
                                if(SD_SUCCESS != SDC_PutSector(file->SectorInCache, file->Cache))
1913
                                if(SD_SUCCESS != SDC_PutSector(file->SectorInCache, file->Cache))
1811
                                {
1914
                                {
1812
                                        Fat16_Deinit();
1915
                                        Fat16_Deinit();
1813
                                        return(EOF);
1916
                                        return(EOF);
1814
                                }
1917
                                }
Line 1907... Line 2010...
1907
        while((object_cnt < count) && success)
2010
        while((object_cnt < count) && success)
1908
        {
2011
        {
1909
                object_size = size;
2012
                object_size = size;
1910
                while((size > 0) && success)
2013
                while((size > 0) && success)
1911
                {
2014
                {
1912
                        c = fputc_(*pbuff, file);                                                                               // write a byte from the buffer to the opened file.
2015
                        c = fputc_(*pbuff, file);                                                                                       // write a byte from the buffer to the opened file.
1913
                        if(c != EOF)
2016
                        if(c != EOF)
1914
                        {
2017
                        {
1915
                                pbuff++;
2018
                                pbuff++;
1916
                                size--;
2019
                                size--;
1917
                        }
2020
                        }
Line 1921... Line 2024...
1921
                        }
2024
                        }
1922
                }
2025
                }
1923
                if(success) object_cnt++;
2026
                if(success) object_cnt++;
1924
        }
2027
        }
Line 1925... Line 2028...
1925
 
2028
 
1926
        return(object_cnt);                                                                                                                             // return the number of objects succesfully written to the file
2029
        return(object_cnt);             // return the number of objects succesfully written to the file
Line 1927... Line 2030...
1927
}
2030
}
1928
 
2031
 
Line 1986... Line 2089...
1986
        *pbuff = 0;     // set string terminator
2089
        *pbuff = 0;     // set string terminator
1987
        return(string);
2090
        return(string);
1988
}
2091
}
Line 1989... Line 2092...
1989
 
2092
 
-
 
2093
/****************************************************************************************************************************************/
-
 
2094
/*      Function:               fclose_(File *file);                                                                                                                                                                                            */
-
 
2095
/*                                                                                                                                                                                                                                                                              */
-
 
2096
/*      Description:    This function closes the open file by writing the remaining data                                                                                                        */
-
 
2097
/*                                      from the buffer to the device and entering the filesize in the directory entry.                                                                         */
-
 
2098
/*                                                                                                                                                                                                                                                                              */
-
 
2099
/*      Returnvalue:    0 on success EOF on error                                                                                                                                                                                       */
-
 
2100
/****************************************************************************************************************************************/
-
 
2101
s16 fclose_(File_t *file)
-
 
2102
{
-
 
2103
        s16 returnvalue = EOF;
-
 
2104
 
-
 
2105
        if(file == NULL) return(returnvalue);
-
 
2106
        returnvalue = fflush_(file);
-
 
2107
        UnlockFilePointer(file);
-
 
2108
        return(returnvalue);
-
 
2109
}
-
 
2110
 
-
 
2111
 
1990
/****************************************************************************************************************************************/
2112
/****************************************************************************************************************************************/
1991
/*      Function:               fexist_(const u8*);                                                                                                                                                                                                     */
2113
/*      Function:               fexist_(const u8*);                                                                                                                                                                                                     */
1992
/*                                                                                                                                                                                                                                                                              */
2114
/*                                                                                                                                                                                                                                                                              */
1993
/*      Description:    This function checks if a file already exist.                                                                                                                                           */
2115
/*      Description:    This function checks if a file already exist.                                                                                                                                           */
1994
/*                                                                                                                                                                                                                                                                              */
2116
/*                                                                                                                                                                                                                                                                              */
Line 2021... Line 2143...
2021
        {
2143
        {
2022
                return(1);
2144
                return(1);
2023
        }
2145
        }
2024
}
2146
}
Line -... Line 2147...
-
 
2147
 
-
 
2148
 
-
 
2149
/********************************************************************************************************************************************/
-
 
2150
/*      Function:               fdelete_(s8* filepath);                                                                                                                                                                                                 */
-
 
2151
/*                                                                                                                                                                                                                                                                                      */
-
 
2152
/*      Description:    This function deletes the file with the specified filename from the filesystem                                                                                  */
-
 
2153
/*                                                                                                                                                                                                                                      */
-
 
2154
/*                                                                                                                                                                                                                                                                                      */
-
 
2155
/*      Returnvalue:    1 : specified file deleted succesfully 0: specified file not found                                                                                                              */
-
 
2156
/********************************************************************************************************************************************/
-
 
2157
 
-
 
2158
u8 fdelete_(s8* const filepath)
-
 
2159
{
-
 
2160
        u8 retvalue = 0;
-
 
2161
        File_t file;
-
 
2162
 
-
 
2163
        if(filepath == NULL) return(0);
-
 
2164
        // correct filepath formatting
-
 
2165
        Slashing_Path(filepath);
-
 
2166
        // if file is existent
-
 
2167
        if(FileExist(filepath, ATTR_NONE, ATTR_SUBDIRECTORY|ATTR_VOLUMELABEL, &file))
-
 
2168
        {
-
 
2169
                // and is not marked as readonly?
-
 
2170
                if((file.Attribute & ATTR_READONLY) != ATTR_READONLY)
-
 
2171
                {
-
 
2172
                        // try to delete the file content from the filesystem
-
 
2173
                        if(DeleteClusterChain(file.FirstSectorOfFirstCluster))
-
 
2174
                        {
-
 
2175
                                // and try delete the directory entry of the file
-
 
2176
                                retvalue = DeleteDirectoryEntry(&file);
-
 
2177
                        }      
-
 
2178
                }
-
 
2179
        }
-
 
2180
        return(retvalue);
-
 
2181
}
2025
 
2182
 
2026
/****************************************************************************************************************************************************/
2183
/****************************************************************************************************************************************************/
2027
/* Function:    s8* FAT16_GetVolumeLabel(void)                                                                                                                                                                                                                  */
2184
/* Function:    s8* FAT16_GetVolumeLabel(void)                                                                                                                                                                                                                  */
2028
/*                                                                                                                                                                                                                                                                                                      */
2185
/*                                                                                                                                                                                                                                                                                                      */
2029
/* Description: This function returns the volume label                                                                                                                                                                                          */
2186
/* Description: This function returns the volume label                                                                                                                                                                                          */
Line 2037... Line 2194...
2037
        u16     dir_entry = 0;
2194
        u16     dir_entry = 0;
2038
        u8              i = 0;
2195
        u8              i = 0;
Line 2039... Line 2196...
2039
 
2196
 
2040
        DirEntry_t * dir;
2197
        DirEntry_t * dir;
2041
        File_t *file = NULL;
2198
        File_t *file = NULL;
2042
       
2199
 
2043
        // if Partition is not valud return NULL
2200
        // if Partition is not valid return NULL
2044
        if(!Partition.IsValid) return(pVolumeLabel);
2201
        if(!Partition.IsValid) return(pVolumeLabel);
2045
        // if Volume label was read before return it
2202
        // if Volume label was read before return it
2046
        if(Partition.VolumeLabel[0]!= '\0') return (Partition.VolumeLabel);
2203
        if(Partition.VolumeLabel[0]!= '\0') return (Partition.VolumeLabel);
2047
        // try to catch a file pointer
2204
        // try to catch a file pointer
2048
        file = LockFilePointer();
2205
        file = LockFilePointer();
2049
        if(file == NULL) return(pVolumeLabel);
2206
        if(file == NULL) return(pVolumeLabel);
2050
        // search dir entries direct within the root directory area
2207
        // search dir entries direct within the root directory area
2051
        file->DirectorySector = 0;
2208
        file->DirectorySector = 0;
2052
        max_dir_sector = (Partition.MaxRootEntries * DIRENTRY_SIZE)/BYTES_PER_SECTOR;
2209
        max_dir_sector = (Partition.MaxRootEntries * DIRENTRY_SIZE)/BYTES_PER_SECTOR;
2053
        file->FirstSectorOfFirstCluster = Partition.FirstRootDirSector;
2210
        file->FirstSectorOfFirstCluster = Partition.FirstRootDirSector;
2054
       
2211
 
2055
        // update current file data area position to start of first cluster
2212
        // update current file data area position to start of first cluster
2056
        file->FirstSectorOfCurrCluster  = file->FirstSectorOfFirstCluster;
2213
        file->FirstSectorOfCurrCluster  = file->FirstSectorOfFirstCluster;
2057
        file->SectorOfCurrCluster               = 0;
2214
        file->SectorOfCurrCluster               = 0;
Line 2102... Line 2259...
2102
        UnlockFilePointer(file);
2259
        UnlockFilePointer(file);
2103
        return(pVolumeLabel);
2260
        return(pVolumeLabel);
2104
}
2261
}
Line 2105... Line -...
2105
 
-
 
2106
 
-
 
2107
 
-
 
2108
#define ATTR_NONE               0x00    // normal file
-
 
2109
#define ATTR_READONLY           0x01    // file is readonly
-
 
2110
#define ATTR_HIDDEN                     0x02    // file is hidden
-
 
2111
#define ATTR_SYSTEM                     0x04    // file is a system file
-
 
2112
#define ATTR_VOLUMELABEL        0x08    // entry is a volume label
-
 
2113
#define ATTR_LONG_FILENAME      0x0F    // this is a long filename entry
-
 
2114
#define ATTR_SUBDIRECTORY       0x10    // entry is a directory name
-
 
2115
#define ATTR_ARCHIVE            0x20    // file is new or modified
-
 
2116
 
2262
 
2117
 
2263
 
2118
/********************************************************************************************************************************************/
2264
/********************************************************************************************************************************************/
2119
/*      Function:               u8 FindItem(Find_t);                                                                                                                                                                                                                    */
2265
/*      Function:               u8 FindItem(Find_t);                                                                                                                                                                                                    */
2120
/*                                                                                                                                                                                                                                                                                      */
2266
/*                                                                                                                                                                                                                                                                                      */
2121
/*      Description:    This function looks for the item specified by global structure FindElement in the actual directory                                      */
2267
/*      Description:    This function looks for the item specified by global structure FindElement in the actual directory                                      */
2122
/*                                                                                                                                                                                                                                                              */
2268
/*                                                                                                                                                                                                                                                              */
2123
/*                                                                                                                                                                                                                                                                                      */
2269
/*                                                                                                                                                                                                                                                                                      */
Line 2124... Line 2270...
2124
/*      Returnvalue:    TRUE if an matching element was found                                                                                                                                                                           */
2270
/*      Returnvalue:    TRUE if an matching element was found                                                                                                                                                                   */
2125
/********************************************************************************************************************************************/
2271
/********************************************************************************************************************************************/
2126
 
2272
 
Line 2133... Line 2279...
2133
        u8              readpointer = 0;
2279
        u8              readpointer = 0;
2134
        u8              writepointer = 0;
2280
        u8              writepointer = 0;
2135
        u8              retvalue = 0;
2281
        u8              retvalue = 0;
2136
        DirEntry_t      *DirectoryEntry;
2282
        DirEntry_t      *DirectoryEntry;
2137
        File_t  file;
2283
        File_t  file;
-
 
2284
        SD_Result_t res=0;
Line 2138... Line 2285...
2138
 
2285
 
2139
        file.FirstSectorOfCurrCluster   = findelement->fp.FirstSectorOfCurrCluster;
2286
        file.FirstSectorOfCurrCluster   = findelement->fp.FirstSectorOfCurrCluster;
2140
        file.SectorOfCurrCluster        = findelement->fp.SectorOfCurrCluster;
2287
        file.SectorOfCurrCluster        = findelement->fp.SectorOfCurrCluster;
Line 2150... Line 2297...
2150
        {
2297
        {
2151
                max_dir_sector = Partition.SectorsPerCluster;                           // limit max secters before next cluster
2298
                max_dir_sector = Partition.SectorsPerCluster;                           // limit max secters before next cluster
2152
        }
2299
        }
Line 2153... Line 2300...
2153
 
2300
 
2154
        do
2301
        do
2155
        {                                                                                                                                                               // search the next 16 rootentries in this sector of the roordirectory.          
2302
        {       // search the next 16 rootentries in this sector of the roordirectory.
-
 
2303
                res = SDC_GetSector(((u32) file.FirstSectorOfCurrCluster + (u32)file.SectorOfCurrCluster), file.Cache);                                         // Read the Rootdirectory.
2156
                if(SD_SUCCESS != SDC_GetSector(((u32) file.FirstSectorOfCurrCluster + (u32)file.SectorOfCurrCluster), file.Cache));                                             // Read the Rootdirectory.
2304
                if(res != SD_SUCCESS)
2157
                {
2305
                {
2158
                        Fat16_Deinit();
2306
                        Fat16_Deinit();
2159
                        return(0);
2307
                        return(0);
2160
                }
2308
                }
2161
               
2309
 
Line 2162... Line 2310...
2162
                DirectoryEntry = (DirEntry_t *)file.Cache;
2310
                DirectoryEntry = (DirEntry_t *)file.Cache;
2163
 
2311
 
2164
                while((!retvalue)&&(index<16))
2312
                while((!retvalue)&&(index < 16))
2165
                {
2313
                {
2166
                        i=0;                   
2314
                        i = 0;
2167
                        if((u8) DirectoryEntry[index].Name[0] != 0xe5)                                                          // ignore deleted items.
2315
                        if( (u8)DirectoryEntry[index].Name[0] != SLOT_DELETED)          // ignore deleted items.
2168
                        {
2316
                        {
2169
                                while((i<=10)&&((DirectoryEntry[index].Name[i] == findelement->searchstring[i]) || (findelement->searchstring[i]=='*') || findelement->searchstring[i]=='?'))
2317
                                while((i <= 10) && ( (DirectoryEntry[index].Name[i] == findelement->searchstring[i]) || (findelement->searchstring[i] == '*') || findelement->searchstring[i] == '?'))
2170
                                {
2318
                                {
2171
                                        i++;
2319
                                        i++;
2172
                                }
2320
                                }
2173
                        }
2321
                        }
-
 
2322
                        if((DirectoryEntry[index].Attribute & 0x30) && (DirectoryEntry[index].Attribute & findelement->attribmask) && (i == 11))
-
 
2323
                        {
2174
                        if((DirectoryEntry[index].Attribute <= 0x30) && (DirectoryEntry[index].Attribute & findelement->attribmask) && (i==11))
2324
                /* initialize the namestring with 0 */
2175
                        {
2325
                        for(i = 0; i < 12; i++) findelement->name[i] = 0;
2176
                for(readpointer=0;readpointer<=10;readpointer++)
2326
                for(readpointer = 0; readpointer <= 10; readpointer++)
2177
                                {
2327
                                {
2178
                                        if((DirectoryEntry[index].Name[readpointer] != ' ') && (readpointer!=8))
2328
                                        if((DirectoryEntry[index].Name[readpointer] != ' ') && (readpointer!=8))
2179
                                        {
2329
                                        {
2180
                                                findelement->name[writepointer] = DirectoryEntry[index].Name[readpointer];      // copy the name of the item found to the find_structure.
2330
                                                findelement->name[writepointer] = DirectoryEntry[index].Name[readpointer];      // copy the name of the item found to the find_structure.
2181
                                                writepointer++;
2331
                                                writepointer++;
2182
                                        }
2332
                                        }
2183
                                        else  
2333
                                        else
2184
                                        {
2334
                                        {
2185
                                                if(DirectoryEntry[index].Attribute == ATTR_ARCHIVE)                                            
2335
                                                if(DirectoryEntry[index].Attribute == ATTR_ARCHIVE)
2186
                                                {
2336
                                                {
2187
                                        if(readpointer < 8) readpointer=8;
2337
                                        if(readpointer < 8) readpointer = 8;
2188
                                        if(DirectoryEntry[index].Name[readpointer] != ' ')
2338
                                        if(DirectoryEntry[index].Name[readpointer] != ' ')
2189
                                        {
2339
                                        {
2190
                                        findelement->name[writepointer] = '.';                                                  // then seperate the name and the extension by a '.' at index 8.                                                
2340
                                        findelement->name[writepointer] = '.';                                                  // then seperate the name and the extension by a '.' at index 8.
2191
                                        writepointer++;
2341
                                        writepointer++;
2192
                                        findelement->name[writepointer] = DirectoryEntry[index].Name[readpointer];      // copy the name of the item found to the find_structure.
2342
                                        findelement->name[writepointer] = DirectoryEntry[index].Name[readpointer];      // copy the name of the item found to the find_structure.
2193
                                        writepointer++;
2343
                                        writepointer++;
2194
                                        }
2344
                                        }
2195
                                            else break;
2345
                                            else break;
2196
                                                }
2346
                                                }
2197
                            else break;
-
 
2198
                        }
-
 
2199
                        /* terminate the namestring with 0 for debugpurposes*/
2347
                            else break;
2200
                        findelement->name[12] = 0;
2348
                        }
2201
                                }
2349
                                }
2202
                                findelement->fp.FirstSectorOfFirstCluster = (u32) DirectoryEntry[index].StartCluster;                                                  
2350
                                findelement->fp.FirstSectorOfFirstCluster = (u32) DirectoryEntry[index].StartCluster;
2203
                                findelement->fp.DirectoryIndex   = index;              
2351
                                findelement->fp.DirectoryIndex   = index;
2204
                                findelement->fp.FirstSectorOfCurrCluster   = file.FirstSectorOfCurrCluster;
2352
                                findelement->fp.FirstSectorOfCurrCluster   = file.FirstSectorOfCurrCluster;
2205
                                findelement->fp.DirectorySector  = (file.FirstSectorOfCurrCluster + file.SectorOfCurrCluster);
2353
                                findelement->fp.DirectorySector  = (file.FirstSectorOfCurrCluster + file.SectorOfCurrCluster);
2206
                                findelement->fp.SectorOfCurrCluster      = file.SectorOfCurrCluster;
2354
                                findelement->fp.SectorOfCurrCluster      = file.SectorOfCurrCluster;
2207
                findelement->fp.Size            = DirectoryEntry[index].Size;
2355
                findelement->fp.Size            = DirectoryEntry[index].Size;
2208
                                findelement->fp.Attribute               = DirectoryEntry[index].Attribute;
2356
                                findelement->fp.Attribute               = DirectoryEntry[index].Attribute;
2209
                retvalue = 1;
2357
                retvalue = 1;
2210
                        }                      
2358
                        }
2211
                        /* search the next sector */
2359
                        /* search the next sector */
2212
                        index++;
2360
                        index++;
2213
                }
2361
                }
2214
                /* this sector has been searched but we havn't found what we are looking for. Therefore we have to find the next sector */
2362
                /* this sector has been searched but we havn't found what we are looking for. Therefore we have to find the next sector */
2215
                if(!retvalue)                                                                                                                           // file not found in this sector so take next sector.
2363
                if(!retvalue)                                                                                                                           // file not found in this sector so take next sector.
2216
                {
2364
                {
2217
                        /* in the next sector we start looking for the specified entry beginning at index 0 */
2365
                        /* in the next sector we start looking for the specified entry beginning at index 0 */
2218
                        index = 0;
2366
                        index = 0;
2219
                        /* there are still sectors to be read within the cluster or within the linear addresspace of the rootdirectory */
2367
                        /* there are still sectors to be read within the cluster or within the linear addresspace of the rootdirectory */
2220
                        if(file.SectorOfCurrCluster < max_dir_sector-1)  file.SectorOfCurrCluster++; else end_of_directory_not_reached = 0;
2368
                        if(file.SectorOfCurrCluster < max_dir_sector-1)  file.SectorOfCurrCluster++;
-
 
2369
                        /* 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 */
-
 
2370
                        else if(Partition.FirstDataSector <= file.FirstSectorOfCurrCluster)
-
 
2371
                        {
-
 
2372
                                end_of_directory_not_reached = GetNextCluster(&file);
-
 
2373
                        }
2221
                        /* 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 */
2374
                        // within the rootdirectory we abort searching for elements after the maximun number of possible rootentries has beensearched
2222
                        if(Partition.FirstDataSector <= file.FirstSectorOfCurrCluster)
2375
                        else
2223
                        {
2376
                        {
2224
                                end_of_directory_not_reached = GetNextCluster(&file);
2377
                                end_of_directory_not_reached = 0;
2225
                        }
2378
                        }
2226
                }
2379
                }
Line 2227... Line 2380...
2227
        }
2380
        }
2228
        while((end_of_directory_not_reached) && (!retvalue) );
2381
        while((end_of_directory_not_reached) && (!retvalue) );
Line 2247... Line 2400...
2247
        u8 index = 0;
2400
        u8 index = 0;
Line 2248... Line 2401...
2248
 
2401
 
Line 2249... Line 2402...
2249
        findelement->fp.DirectoryIndex++;
2402
        findelement->fp.DirectoryIndex++;
2250
 
2403
 
Line 2251... Line 2404...
2251
        /* before we start searching an element we clear the complete namestring within the structure FindElement */
2404
        /* before we start searching an element we clear the complete namestring within the structure FindElement */
2252
        for(index=0;index<11;index++) findelement->name[index] = 0;
2405
        for(index = 0; index < 11; index++) findelement->name[index] = 0;
2253
 
2406
 
2254
        if(FindItem(findelement))
2407
        if(FindItem(findelement))
Line 2255... Line 2408...
2255
        {
2408
        {
2256
                itemfound = 1;         
2409
                itemfound = 1;
Line 2271... Line 2424...
2271
/*      Returnvalue:    (1) if Element was found. (0) if no valid element was found                                                                                                                     */
2424
/*      Returnvalue:    (1) if Element was found. (0) if no valid element was found                                                                                                                     */
2272
/********************************************************************************************************************************************/
2425
/********************************************************************************************************************************************/
2273
u8 findfirst_(const s8* name, u8 attribmask, Find_t *findelement)
2426
u8 findfirst_(const s8* name, u8 attribmask, Find_t *findelement)
2274
{
2427
{
2275
        u8 itemfound = 0;
2428
        u8 itemfound = 0;
2276
        u8 index = 0;  
2429
        u8 index = 0;
Line 2277... Line 2430...
2277
 
2430
 
2278
        /* initialize the FindElement structure */
2431
        /* initialize the FindElement structure */
2279
        findelement->fp.FirstSectorOfFirstCluster = 0;  // First sector of the first cluster of the file.
2432
        findelement->fp.FirstSectorOfFirstCluster = 0;                                  // First sector of the first cluster of the file.
2280
        findelement->fp.FirstSectorOfCurrCluster = Partition.CurrentWorkingDirectory;                                   // First sector of the cluster which is edited at the moment.
2433
        findelement->fp.FirstSectorOfCurrCluster = Partition.CurrentWorkingDirectory;   // First sector of the cluster which is edited at the moment.
2281
        findelement->fp.SectorOfCurrCluster = 0;                                                        // The sector within the current cluster.
2434
        findelement->fp.SectorOfCurrCluster = 0;                                                // The sector within the current cluster.
2282
        findelement->fp.ByteOfCurrSector = 0;                                                   // The byte location within the current sector.
2435
        findelement->fp.ByteOfCurrSector = 0;                                                   // The byte location within the current sector.
2283
        findelement->fp.Size = 0;                                                                               // The size of the opend file in bytes.
2436
        findelement->fp.Size = 0;                                                                               // The size of the opend file in bytes.
2284
        findelement->fp.Position = 0;                                                                   // Pointer to a character within the file 0 < fileposition < filesize
2437
        findelement->fp.Position = 0;                                                                   // Pointer to a character within the file 0 < fileposition < filesize
2285
        findelement->fp.DirectorySector = 0;                                                            // the sectorposition where the directoryentry has been made.
2438
        findelement->fp.DirectorySector = 0;                                                    // the sectorposition where the directoryentry has been made.
2286
        findelement->fp.DirectoryIndex = 0;                                                             // The index to the directoryentry within the specified sector.
2439
        findelement->fp.DirectoryIndex = 0;                                                             // The index to the directoryentry within the specified sector.
2287
        findelement->attribfilter = 0;
2440
        findelement->attribfilter = 0;
2288
        findelement->attribmask = attribmask;
2441
        findelement->attribmask = attribmask;
Line 2289... Line 2442...
2289
        findelement->searchstring[0]=0;
2442
        findelement->searchstring[0] = 0;                                                               // terminate string at the begin (=NULL)
2290
 
2443
 
-
 
2444
        // bring it to the 8.3 format
2291
        /* seperate the name of the element to be found from the filepath and bring it to the 8.3*/
2445
        if(NULL == SeperateFormatedDirName(name, findelement->searchstring)) return(0);
2292
        SeperateDirName(name, findelement->searchstring);
2446
 
2293
        /* after the name of the element is in 8.3 we process the wildcards (*). After an * all following character are wildcards to */
2447
        //process the wildcards (*). After an * all following character are wildcards to
2294
        for(index=0;index<8;index++)
2448
        for(index = 0;index < 8;index++)
2295
        {
2449
        {
2296
                /* if we find an wildcard within the name of the searchstring all remaining character after the wildcard shall be wildcards also */
2450
                /* if we find an wildcard within the name of the searchstring all remaining character after the wildcard shall be wildcards also */
2297
                if(findelement->searchstring[index] == '*')
2451
                if(findelement->searchstring[index] == '*')
2298
                {
2452
                {
2299
                        /*  */
2453
                        /*  */
2300
                        while(++index <8) findelement->searchstring[index] = '*';
2454
                        while(++index < 8) findelement->searchstring[index] = '*';
2301
                }
2455
                }
2302
        }
2456
        }
2303
        for(index=8;index<11;index++)
2457
        for(index = 8;index < 11;index++)
2304
        {                                                                                                                                                                                                                                        
2458
        {
2305
                /* if we find an wildcard within the name of the searchstring all remaining character after the wildcard shall be wildcards also */
2459
                /* if we find an wildcard within the name of the searchstring all remaining character after the wildcard shall be wildcards also */
2306
                if(findelement->searchstring[index] == '*')
2460
                if(findelement->searchstring[index] == '*')
2307
                {
2461
                {
2308
                        /*  */
2462
                        /*  */
2309
                        while(++index <11) findelement->searchstring[index] = '*';
2463
                        while(++index < 11) findelement->searchstring[index] = '*';
2310
                }
2464
                }
2311
        }
2465
        }
2312
       
2466
 
2313
        /* the value of ...DirectoryIndex will be incremented in findnext_() thererfore it has to be decremented in findfirst_() */
2467
        /* the value of ...DirectoryIndex will be incremented in findnext_() thererfore it has to be decremented in findfirst_() */
2314
        findelement->fp.DirectoryIndex--;
2468
        findelement->fp.DirectoryIndex--;
Line 2315... Line 2469...
2315
        /* now lets search for the item within the direcory */
2469
        /* now lets search for the item within the direcory */
2316
        itemfound = findnext_(findelement);
2470
        itemfound = findnext_(findelement);
Line 2317... Line -...
2317
 
-
 
2318
        return(itemfound);
-
 
2319
}
-
 
2320
 
-
 
2321
 
-
 
2322
/********************************************************************************************************************************************/
-
 
2323
/*      Function:               u8 GetDirCount(s8* filepath);                                                                                                                                                                                   */
-
 
2324
/*                                                                                                                                                                                                                                                                                      */
-
 
2325
/*      Description:    This function counts the number of subdirectories the dirpath contains                                                                                                  */
-
 
2326
/*                                                                                                                                                                                                                                                              */
-
 
2327
/*                                                                                                                                                                                                                                                                                      */
-
 
2328
/*      Returnvalue:    then number of subdirectories within the specified path                                                                                                                                 */
-
 
2329
/********************************************************************************************************************************************/
-
 
2330
u8 GetDirCount(u8 *dirpath)
-
 
2331
{
-
 
2332
   u8 i=0;
-
 
2333
   u8 cnt=0;
-
 
2334
 
-
 
2335
   while(dirpath[i] != 0 )
-
 
2336
   {
-
 
2337
      if(dirpath[i]=='/')
-
 
2338
      {  
-
 
2339
         if(dirpath[i+1]!=0) cnt++;                                            // ignore last'/'
-
 
2340
      }
-
 
2341
      i++;  
-
 
2342
   }
-
 
2343
   i=0;  
-
 
2344
   return(cnt);
2471
 
2345
}
2472
        return(itemfound);
2346
 
2473
}
2347
 
2474
 
2348
/********************************************************************************************************************************************/
2475
/********************************************************************************************************************************************/
2349
/* Funtion:     char *GetSubDirectory (char *dirpath, char *directory)                                                                                                                                          */
2476
/* Function:    s8 *GetSubDirectory (s8 *dirpath, s8 *directory)                                                                                                                                                        */
2350
/*                                                                                                                                                                                                                                                                                      */
2477
/*                                                                                                                                                                                                                                                                                      */
2351
/* Description: this function returns a pointer to the beginning of the next subdirectory or NULL                                                                                       */
2478
/* Description: this function parses the dirpath string and copies the first directroy name to the location pointed to by directroy                     */
2352
/*                                                                                                                                                                                                                                                                                      */
2479
/*                                                                                                                                                                                                                                                                                      */
2353
/*                                                                                                                                                                                                                                                                                      */
2480
/*                                                                                                                                                                                                                                                                                      */
2354
/* returnvalue:   number of subdirectories in the filepath                                                                                                                                                                      */
2481
/* returnvalue:  a pointer to the beginning of the next subdirectory or NULL                                                                                                                            */
2355
/********************************************************************************************************************************************/
2482
/********************************************************************************************************************************************/
2356
u8 * GetSubDirectory(u8 *dirpath, u8 *directory)
2483
s8 * GetSubDirectory(s8 *dirpath, s8 *directory)
2357
{
2484
{
2358
   u8 *cptr = dirpath;
2485
   s8 *cptr = dirpath;
2359
   u8 *dptr = directory;
2486
   s8 *dptr = directory;
2360
   u8 *retvalue = NULL;
2487
   s8 *remainingpath = NULL;
2361
       
2488
 
2362
   /* if the first character of the path is an '/' we go to the next character */
2489
   /* if the first character of the path is an '/' we go to the next character */
2363
   if(*cptr == '/') cptr++;
2490
   if(*cptr == '/') cptr++;
2364
   /* search end of path or subdirectory*/
2491
   /* search end of path or subdirectory*/
2365
   while((*cptr != 0) && (*cptr != '/'))
2492
   while((*cptr != 0) && (*cptr != '/'))
2366
   {
2493
   {
2367
      *dptr = *cptr;
2494
      *dptr = *cptr;   // copy to directory string buffer
2368
       dptr++;
2495
       dptr++;
Line 2369... Line 2496...
2369
       cptr++;
2496
       cptr++;
2370
   }  
2497
   }
Line -... Line 2498...
-
 
2498
   if(*cptr!=0) remainingpath = ++cptr; // return pointer to remaining path string
2371
   if(*cptr!=0) retvalue = ++cptr;
2499
   *dptr = 0; // terminate directory name string
2372
   *dptr = 0;
2500
 
2373
 
2501
   return(remainingpath);
2374
   return(retvalue);
2502
}
2375
}
2503
 
2376
 
2504
 
2377
/********************************************************************************************************************************************/
2505
/********************************************************************************************************************************************/
2378
/*      Function:               s8 *GetPath(void);                                                                                                                                                                                                              */
2506
/*      Function:               u8 chdir_(s8* const path);                                                                                                                                                                                              */
Line 2379... Line 2507...
2379
/*                                                                                                                                                                                                                                                                                      */
2507
/*                                                                                                                                                                                                                                                                                      */
2380
/*      Description:    This function function returns a pointer to the absolute path of the active partition                                                                   */
2508
/*      Description:    This function changes the current working directory to the directory specified by the filepath                                                  */
-
 
2509
/*                  by function findfirst()                                                                                                                                                                                                     */
2381
/*                                                                                                                                                                                                                                      */
2510
/*                                                                                                                                                                                                                                                                                      */
2382
/*                                                                                                                                                                                                                                                                                      */
-
 
-
 
2511
/*      Returnvalue:                                                                                                                                                                                                                                                    */
-
 
2512
/********************************************************************************************************************************************/
-
 
2513
 
-
 
2514
u8 chdir_(s8* const path)
-
 
2515
{
Line 2383... Line -...
2383
/*      Returnvalue:                                                                                                                                                                                                                                                    */
-
 
2384
/********************************************************************************************************************************************/
2516
        u8              retvalue = 0;                                   // the value returned by this function
2385
 
2517
        u32     ultemp = 0;                                             // temp. variable
2386
s8 *GetPath(void)
-
 
2387
{
-
 
2388
        return(Partition.PathToCwd);
2518
        s8      *dirpath = path;                                // pointer to the remaining path string
2389
}
-
 
2390
 
-
 
Line 2391... Line -...
2391
/********************************************************************************************************************************************/
-
 
2392
/*      Function:               void SetPathToRoot(void);                                                                                                                                                                                                       */
-
 
2393
/*                                                                                                                                                                                                                                                                                      */
2519
        s8      dirname[64];                                    // a buffer containing the name of the subdirectory we are actually looking for
2394
/*      Description:    This function sets the path to the rootdirectory                                                                                                                                                */
2520
        Find_t  fe;                                                             // The findelement needed for function findfirst to find the subdirectory entry
2395
/*                                                                                                                                                                                                                                      */
-
 
-
 
2521
        s8              tp[256];                                                // temporarily we remember the actual path until the operation has finished successfully
Line -... Line 2522...
-
 
2522
        u32     tcwd = 0;                                               // temporarily we remember the actual current working directory
-
 
2523
 
-
 
2524
        if(path == NULL) return(0);                             // return immediately of no path is given
-
 
2525
        // correct filepath formatting
-
 
2526
        Slashing_Path(path);
-
 
2527
 
-
 
2528
        // lets remember the actual path and correspondig directory sector
-
 
2529
        strcpy(tp, Partition.PathToCwd);
2396
/*                                                                                                                                                                                                                                                                                      */
2530
        tcwd = Partition.CurrentWorkingDirectory;
2397
/*      Returnvalue:                                                                                                                                                                                                                                                    */
2531
 
-
 
2532
        if(path[0] == '/') // if the path is absolute we begin at the rootdirectory
-
 
2533
        {
2398
/********************************************************************************************************************************************/
2534
                strcpy(Partition.PathToCwd, "/");
-
 
2535
                Partition.CurrentWorkingDirectory = Partition.FirstRootDirSector;
-
 
2536
        }
-
 
2537
        // parse through all the subdirectories within the path
-
 
2538
        do
2399
 
2539
        {
-
 
2540
                dirpath = GetSubDirectory(dirpath, dirname); // get the name of the subdirectory we are looking for and the remainig path
2400
void SetPathToRoot(void)
2541
                if(dirname[0] == 0)             // if no directory name is available 
2401
{
2542
                {
-
 
2543
                        retvalue = 1;                   // we are done
-
 
2544
                        break;                                  // break the loop
-
 
2545
                }      
-
 
2546
                // search for the next subdirectory within the path
2402
        /* lets point to the rootdirectory */
2547
                if(findfirst_(dirname, ATTR_SUBDIRECTORY, &fe))
-
 
2548
                {
-
 
2549
                        // we try to change into the directory "..". Now we have to delete the last direntry from the path
-
 
2550
                        if(strcmp(dirname, "..") == 0) CWDPath_Pop();
-
 
2551
                        // we try to change into the actual directory so there's nothing todo
-
 
2552
                        else if(dirname[0] == '.') return(1);
-
 
2553
                        // otherwise we append the name of the directory we are changing in to the path
2403
        strcpy(Partition.PathToCwd, "/");      
2554
                        else CWDPath_Push(dirname);
-
 
2555
                        // The startcluster within an directory entry specifies the position within the fat where the file or directory starts
-
 
2556
                        ultemp = (u32) fe.fp.FirstSectorOfFirstCluster;
-
 
2557
                        // do we have to change into the rootdirectory?
-
 
2558
                        if(ultemp)
-
 
2559
                        {
-
 
2560
                                // the first 2 entries are reserved for '.' and '..' 
-
 
2561
                                ultemp -= 2;
-
 
2562
                                // 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
-
 
2563
                                ultemp *= Partition.SectorsPerCluster;
-
 
2564
                                // at least we make the sectoraddress absolute by adding the relative address to the beginning of the datasection of the active partition
-
 
2565
                                ultemp += Partition.FirstDataSector;
-
 
2566
                                // the cwd now points to the specified directory
-
 
2567
                                Partition.CurrentWorkingDirectory = ultemp;
-
 
2568
                        }
-
 
2569
                        else // (=0) root directory 
-
 
2570
                        {
-
 
2571
                                // the cwd now points to the rootdirectory
-
 
2572
                                Partition.CurrentWorkingDirectory = Partition.FirstRootDirSector;
Line 2404... Line 2573...
2404
}
2573
                        }
-
 
2574
                        retvalue = 1;
2405
 
2575
                }
2406
/********************************************************************************************************************************************/
2576
                else // subdirectory not found
2407
/*      Function:               void AppendDirToPath(s8* directory);                                                                                                                                                                                    */
2577
                {
2408
/*                                                                                                                                                                                                                                                                                      */
-
 
-
 
2578
                        retvalue = 0;           // no success tracing along the given directory chain
2409
/*      Description:    This function function appends the name of an directory to the Path to the CWD                                                                                  */
2579
                        break;                          // break the loop
2410
/*                                                                                                                                                                                                                                      */
2580
                }
Line -... Line 2581...
-
 
2581
        }
2411
/*                                                                                                                                                                                                                                                                                      */
2582
        while(dirpath != NULL);  // do this until all subdirectories have been found
2412
/*      Returnvalue:                                                                                                                                                                                                                                                    */
2583
 
2413
/********************************************************************************************************************************************/
2584
        // if we could not change to the specified directory we restore the actual path 
2414
 
2585
        if(!retvalue)
2415
void AppendDirToPath(s8* directory)
2586
        {
2416
{
2587
                Partition.CurrentWorkingDirectory = tcwd;
2417
        /* append the name of the directory to the path */
2588
                strcpy(Partition.PathToCwd, tp);
2418
        strcat(Partition.PathToCwd, directory);
2589
        }
Line 2419... Line 2590...
2419
        /* append a '/' after the directoryname */
2590
        return(retvalue);
2420
        strcat(Partition.PathToCwd, "/");
2591
}
-
 
2592
 
-
 
2593
 
-
 
2594
/********************************************************************************************************************************************/
-
 
2595
/*      Function:               u8 rmdir_(s8* dname);                                                                                                                                                                                                           */
-
 
2596
/*                                                                                                                                                                                                                                                                                      */
-
 
2597
/*      Description:    This function deletes the directory with the specified filename from the filesystem                                                                             */
-
 
2598
/*                                                                                                                                                                                                                                      */
-
 
2599
/*                                                                                                                                                                                                                                                                                      */
-
 
2600
/*      Returnvalue:    1 : specified directory deleted succesfully 0: specified directory not found                                                                                    */
-
 
2601
/********************************************************************************************************************************************/
-
 
2602
 
2421
}
2603
u8 rmdir_(s8* const dirpath)
-
 
2604
{
-
 
2605
        u8 retvalue = 0;
2422
 
2606
        Find_t fe;
-
 
2607
        u32 cwd;
-
 
2608
        s8 path[256];
-
 
2609
        s8 *dn;
-
 
2610
        s8 *dp;
-
 
2611
 
2423
/********************************************************************************************************************************************/
2612
        if(dirpath == NULL) return(0);
2424
/*      Function:               RemoveLastDirFromPath(void);                                                                                                                                                                                    */
2613
        // correct filepath formatting
2425
/*                                                                                                                                                                                                                                                                                      */
2614
        Slashing_Path(dirpath);
2426
/*      Description:    This function removes the last directory from the path to the cwd                                                                                                               */
2615
 
2427
/*                                                                                                                                                                                                                                      */
2616
    // remember the current workingdirectory
2428
/*                                                                                                                                                                                                                                                                                      */
2617
        cwd = Partition.CurrentWorkingDirectory;
2429
/*      Returnvalue:                                                                                                                                                                                                                                                    */
2618
 
2430
/********************************************************************************************************************************************/
2619
        // create local copy of the path
2431
 
2620
        strcpy(path, dirpath);
2432
void RemoveLastDirFromPath(void)
2621
        // seperate the filepath from the last directory within the path that shall be deleted
2433
{
2622
        // start searching for the name of the directory to be deleted from the beginning of the path
-
 
2623
        dn = path;
-
 
2624
        dp = path;
2434
        /* a pointer to the beginning of the absolute path to the cwd */
2625
        // search the complete path until the end of the string is found
2435
        s8 * cptr = Partition.PathToCwd;
2626
        while(*dn != 0) dn++;
2436
        /* lets find the end of the path to the cwd */
2627
        // now check if the last directory whithin the path is terminated with an '/' and remove the '/' from the directoryname
2437
        while(*cptr != 0 ) cptr++;
2628
        if(*(dn-1) == '/') *--dn = 0;
-
 
2629
        // now find the beginning of the last directoryentry
-
 
2630
        while((*dn != '/') && (dn > path)) dn--;
-
 
2631
        // beginning of the last directory found
-
 
2632
        if(*dn == '/')
-
 
2633
        {
-
 
2634
                // remove the directoryname from the path by terminating the path with 0
2438
        /* if the path is terminated with an '/' */
2635
                *dn = 0;
-
 
2636
                // the dirname begins 1 character after the terminated path
-
 
2637
                dn++;
-
 
2638
        }
-
 
2639
        // we couldn't find a path before the directory to be deleted or no directoryname at all
-
 
2640
        else
-
 
2641
        {
-
 
2642
                // there is no path before the name of the directory to be deleted
-
 
2643
                if(dn == path)
-
 
2644
                {
-
 
2645
                        // if there is a name of a directory to be deleted?
-
 
2646
                        if(*dn == 0) return(0);
-
 
2647
                        // the directory to be deleted is within the actual directory therefore we don't have to change the directory before deleting the directory
-
 
2648
                        dp = NULL;
-
 
2649
                }
-
 
2650
 
-
 
2651
        }
-
 
2652
        // switch to the directory containing the directory to be deleted if neccessary
-
 
2653
        if(dp != NULL)
-
 
2654
        {
-
 
2655
                if(!chdir_(dp)) return(0);
-
 
2656
        }
-
 
2657
        // now we have to find the specified directory to be deleted
-
 
2658
        retvalue = findfirst_(dn, 0xff, &fe);
-
 
2659
        // was the specified directory found?
-
 
2660
        if(retvalue)
-
 
2661
        {
-
 
2662
                // before we delete the directory we check if the directory is empty
-
 
2663
                if(chdir_(dn))
-
 
2664
                {
-
 
2665
                        if(findfirst_("*.*", 0xff, &fe))
-
 
2666
                        {
-
 
2667
                                // within an directory that shall be deleted only the entries . and .. are allowed
-
 
2668
                                if((strncmp(fe.name, ".", 1) != 0) && (strncmp(fe.name, "..", 2) != 0)) retvalue = 0;
-
 
2669
                                while(findnext_(&fe))
-
 
2670
                                {
2439
        if((*(cptr-1)) == '/') *(cptr-1)=0;    
2671
                                        if((strncmp(fe.name, ".", 1) != 0) && (strncmp(fe.name, "..", 2) != 0)) retvalue = 0;
-
 
2672
                                }
-
 
2673
                        }
-
 
2674
                        chdir_("..");
-
 
2675
                }
-
 
2676
                // directory couldn't be entered, is a real file?
-
 
2677
                else
-
 
2678
                {
-
 
2679
                        retvalue = 0;
-
 
2680
                }
-
 
2681
                // specified directory is empty
-
 
2682
                if(retvalue)
2440
        /* now lets find the beginning of the last directorientry */
2683
                {
-
 
2684
                        retvalue = 0;
-
 
2685
                        // we have modified the result of the findfirst_ operation therefore we have to redo findfirst_ to get detailed infos about the directory entry to be deleted
-
 
2686
                        if(findfirst_(dn, 0xff, &fe))
-
 
2687
                        {
-
 
2688
                                // try to clear the allocated clusters within the fat
2441
        while((*cptr != '/' ) && cptr > Partition.PathToCwd) cptr--;
2689
                                if(DeleteClusterChain(fe.fp.FirstSectorOfFirstCluster))
Line -... Line 2690...
-
 
2690
                                {
2442
        /* is there one subdirectory left within the path? */
2691
                                        // delete the directoryentry within the specified directory
2443
        if(cptr > Partition.PathToCwd)
2692
                                        if(DeleteDirectoryEntry(&(fe.fp))) retvalue = 1;
2444
        {
2693
                                }
2445
                /* we delete the direntry by terminating the path with 0 */
2694
                        }
2446
                *cptr = 0;
2695
                }
2447
        }
2696
        }
2448
        /* there is no subdirectory left within the path. Therefore we create the root instead. */
2697
 
2449
        else
2698
        // restore the actual path
2450
        {
-
 
2451
                *cptr = '/';
-
 
2452
                *(cptr+1) = 0;
-
 
2453
        }
-
 
2454
}
-
 
2455
 
-
 
2456
/********************************************************************************************************************************************/
-
 
2457
/*      Function:               chdir_(s8* filepath);                                                                                                                                                                                                   */
-
 
2458
/*                                                                                                                                                                                                                                                                                      */
-
 
2459
/*      Description:    This function changed the current working directory to the directory specified by the filepath                                                  */
-
 
Line 2460... Line 2699...
2460
/*                  by function findfirst()                                                                                                                                                                                                     */
2699
        Partition.CurrentWorkingDirectory = cwd;
2461
/*                                                                                                                                                                                                                                                                                      */
2700
 
2462
/*      Returnvalue:                                                                                                                                                                                                                                                    */
-
 
2463
/********************************************************************************************************************************************/
-
 
2464
/*                                                                         
-
 
2465
#define ATTR_NONE               0x00    // normal file
-
 
2466
#define ATTR_READONLY           0x01    // file is readonly
-
 
2467
#define ATTR_HIDDEN                     0x02    // file is hidden
-
 
2468
#define ATTR_SYSTEM                     0x04    // file is a system file
-
 
2469
#define ATTR_VOLUMELABEL        0x08    // entry is a volume label
2701
        return(retvalue);
2470
#define ATTR_LONG_FILENAME      0x0F    // this is a long filename entry
2702
}
Line 2471... Line -...
2471
#define ATTR_SUBDIRECTORY       0x10    // entry is a directory name
-
 
2472
#define ATTR_ARCHIVE            0x20    // file is new or modified
-
 
2473
*/
-
 
2474
 
-
 
2475
u8 chdir_(s8 *path)
-
 
2476
{
2703
 
2477
        u8              retvalue = 0;                                   // the value returned by this function
-
 
2478
        u32     ultemp = 0;                                             // temp. variable
-
 
2479
        u8     *directory = path;                               // pointer to a directoryname within the path
2704
 
2480
        u8      dircount = 0;                                   // the number of subdirectoryentries within the path
-
 
2481
        u8      cache[64];                                              // a buffer containing the name of the subdirectory we are actually looking for
-
 
2482
        Find_t  fe;                                                             // The findelement needed for function findfirst to find the subdirectoryentry
-
 
2483
        s8              tp[256];                                                // temporarily we remember the actual path until the operation has finished successfully
2705
/********************************************************************************************************************************************/
2484
        u32     cwdt = 0;
-
 
2485
        s8     *cptr;
-
 
2486
 
-
 
2487
        /* bring the path into the correct syntax */
-
 
2488
        cptr = path;
-
 
2489
        /* search the whole string */
-
 
2490
        while(*cptr != 0 )
-
 
2491
        {
-
 
2492
                if(*cptr == '\\') *cptr = '/';
-
 
2493
                cptr++;
-
 
2494
        }
-
 
2495
        /* lets remember the actual path */
-
 
2496
        strcpy(tp, Partition.PathToCwd);
2706
/*      Function:               mkdir_(s8* dirpath);                                                                                                                                                                                                    */
2497
        cwdt = Partition.CurrentWorkingDirectory;
-
 
2498
        /* how many subdirectories are there within the path? */
-
 
2499
        dircount = GetDirCount(path);  
-
 
2500
        /* if the path is absolute we begin at the rootdirectory */
2707
/*                                                                                                                                                                                                                                                                                      */
2501
        if(path[0] == '/')
-
 
2502
        {
-
 
2503
                strcpy(Partition.PathToCwd, "/");
-
 
2504
                Partition.CurrentWorkingDirectory = Partition.FirstRootDirSector;
-
 
2505
                /* if there is no other pathinformation we only switch to the rootdirectory. So theres nothing left todo.*/
-
 
2506
                if(!dircount) return(1);
-
 
2507
        }
-
 
2508
        /* now we parse through all the subdirectories within the path */
-
 
2509
        do
-
 
2510
        {  
-
 
2511
                /* until all the subdirectories within the path have been processed */
-
 
2512
        if(dircount) dircount--;
-
 
2513
                /* this is the name of the next subdirectory we are looking for */             
-
 
2514
            directory = GetSubDirectory(directory, cache);  
-
 
2515
                /* search for the next subdirectory within the path */
-
 
2516
                if(findfirst_(cache, ATTR_SUBDIRECTORY, &fe))
-
 
2517
                {
-
 
2518
                        /* we try to change into the directory "..". Now we have to delete the last direntry from the path */
-
 
2519
                        if(strcmp(cache,"..") == 0) RemoveLastDirFromPath();
-
 
2520
                        /* we try to change into the actual directory so there's nothing todo */
-
 
2521
                        else if(cache[0] == '.') return(1);
-
 
2522
                        /* otherwise we append the name of the directory we are changing in to the path */
-
 
2523
                        else AppendDirToPath(cache);
-
 
2524
                        /* The startcluster within an directoryentry specifies the position within the fat where the file or directory starts */
-
 
2525
                        ultemp = (u32) fe.fp.FirstSectorOfFirstCluster;
-
 
2526
                        /* the first 2 entries are reserved for '.' and '..' */
-
 
2527
                        ultemp -= 2;
2708
/*      Description:    This function creates the directory with the specified pathname in the filesystem                                                                               */
2528
                        /* 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*/
2709
/*                                                                                                                                                                                                                                      */
2529
                        ultemp *= Partition.SectorsPerCluster;
-
 
2530
                        /* at least we make the sectoraddress absolute by adding the relative address to the beginning of the datasection of the active partition */
2710
/*                                                                                                                                                                                                                                                                                      */
2531
                        ultemp += Partition.FirstDataSector;
2711
/*      Returnvalue:    1 : specified directory created succesfully 0: specified dir exist already                                                                                              */
2532
                        /* the cwd now points to the specified directory */
2712
/********************************************************************************************************************************************/
-
 
2713
 
-
 
2714
u8 mkdir_(s8* const dirpath)
-
 
2715
{
-
 
2716
        u8 retvalue = 0;
-
 
2717
        File_t file;
-
 
2718
 
-
 
2719
        if(dirpath == NULL) return(0);