diff --git a/cube/libfat-frag/include/fat.h b/cube/libfat-frag/include/fat.h deleted file mode 100644 index 03e83a21..00000000 --- a/cube/libfat-frag/include/fat.h +++ /dev/null @@ -1,122 +0,0 @@ -/* - fat.h - Simple functionality for startup, mounting and unmounting of FAT-based devices. - - Copyright (c) 2006 - 2012 - Michael "Chishm" Chisholm - Dave "WinterMute" Murphy - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#ifndef _LIBFAT_H -#define _LIBFAT_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include "libfatversion.h" - -// When compiling for NDS, make sure NDS is defined -#ifndef NDS - #if defined ARM9 || defined ARM7 - #define NDS - #endif -#endif - -#include - -#if defined(__gamecube__) || defined (__wii__) -# include -#else -# ifdef NDS -# include -# else -# include -# endif -#endif - -/* -Initialise any inserted block-devices. -Add the fat device driver to the devoptab, making it available for standard file functions. -cacheSize: The number of pages to allocate for each inserted block-device -setAsDefaultDevice: if true, make this the default device driver for file operations -*/ -extern bool fatInit (uint32_t cacheSize, bool setAsDefaultDevice); - -/* -Calls fatInit with setAsDefaultDevice = true and cacheSize optimised for the host system. -*/ -extern bool fatInitDefault (void); - -/* -Mount the device pointed to by interface, and set up a devoptab entry for it as "name:". -You can then access the filesystem using "name:/". -This will mount the active partition or the first valid partition on the disc, -and will use a cache size optimized for the host system. -*/ -extern bool fatMountSimple (const char* name, const DISC_INTERFACE* interface); - -/* -Mount the device pointed to by interface, and set up a devoptab entry for it as "name:". -You can then access the filesystem using "name:/". -If startSector = 0, it will mount the active partition of the first valid partition on -the disc. Otherwise it will try to mount the partition starting at startSector. -cacheSize specifies the number of pages to allocate for the cache. -This will not startup the disc, so you need to call interface->startup(); first. -*/ -extern bool fatMount (const char* name, const DISC_INTERFACE* interface, sec_t startSector, uint32_t cacheSize, uint32_t SectorsPerPage); - -/* -Unmount the partition specified by name. -If there are open files, it will attempt to synchronise them to disc. -*/ -extern void fatUnmount (const char* name); - -/* -Get Volume Label -*/ -extern void fatGetVolumeLabel (const char* name, char *label); - -// File attributes -#define ATTR_ARCHIVE 0x20 // Archive -#define ATTR_DIRECTORY 0x10 // Directory -#define ATTR_VOLUME 0x08 // Volume -#define ATTR_SYSTEM 0x04 // System -#define ATTR_HIDDEN 0x02 // Hidden -#define ATTR_READONLY 0x01 // Read only - -/* -Methods to modify DOS File Attributes -*/ -int FAT_getAttr(const char *file); -int FAT_setAttr(const char *file, int attr ); - -#define LIBFAT_FEOS_MULTICWD - -#ifdef __cplusplus -} -#endif - -#endif // _LIBFAT_H diff --git a/cube/libfat-frag/include/libfatversion.h b/cube/libfat-frag/include/libfatversion.h deleted file mode 100644 index 791c2cd7..00000000 --- a/cube/libfat-frag/include/libfatversion.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef __LIBFATVERSION_H__ -#define __LIBFATVERSION_H__ - -#define _LIBFAT_MAJOR_ 1 -#define _LIBFAT_MINOR_ 0 -#define _LIBFAT_PATCH_ 12 - -#define _LIBFAT_STRING "libFAT Release 1.0.12" - -#endif // __LIBFATVERSION_H__ diff --git a/cube/libfat-frag/src/Makefile b/cube/libfat-frag/src/Makefile deleted file mode 100644 index f6081ef7..00000000 --- a/cube/libfat-frag/src/Makefile +++ /dev/null @@ -1,106 +0,0 @@ -ifeq ($(strip $(DEVKITPRO)),) -$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=devkitPro) -endif - -export TOPDIR := $(CURDIR) - -export LIBFAT_MAJOR := 1 -export LIBFAT_MINOR := 0 -export LIBFAT_PATCH := 12 - -export VERSTRING := $(LIBFAT_MAJOR).$(LIBFAT_MINOR).$(LIBFAT_PATCH) - - -default: release - -all: release dist - -release: nds-release gba-release cube-release wii-release - -ogc-release: include/libfatversion.h cube-release wii-release - -nds-release: include/libfatversion.h - $(MAKE) -C nds BUILD=release - -gba-release: include/libfatversion.h - $(MAKE) -C gba BUILD=release - -cube-release: include/libfatversion.h - $(MAKE) -C libogc PLATFORM=cube BUILD=cube_release - -wii-release: include/libfatversion.h - $(MAKE) -C libogc PLATFORM=wii BUILD=wii_release - -debug: nds-debug gba-debug cube-debug wii-debug - -ogc-debug: cube-debug wii-debug - -nds-debug: include/libfatversion.h - $(MAKE) -C nds BUILD=debug - -gba-debug: include/libfatversion.h - $(MAKE) -C gba BUILD=debug - - -cube-debug: include/libfatversion.h - $(MAKE) -C libogc PLATFORM=cube BUILD=wii_debug - -wii-debug: include/libfatversion.h - $(MAKE) -C libogc PLATFORM=wii BUILD=cube_debug - -clean: nds-clean gba-clean ogc-clean - -nds-clean: - $(MAKE) -C nds clean - -gba-clean: - $(MAKE) -C gba clean - -ogc-clean: - $(MAKE) -C libogc clean - -dist-bin: nds-dist-bin gba-dist-bin ogc-dist-bin - -nds-dist-bin: include/libfatversion.h nds-release distribute/$(VERSTRING) - $(MAKE) -C nds dist-bin - -gba-dist-bin: include/libfatversion.h gba-release distribute/$(VERSTRING) - $(MAKE) -C gba dist-bin - -ogc-dist-bin: include/libfatversion.h ogc-release distribute/$(VERSTRING) - $(MAKE) -C libogc dist-bin - -dist-src: distribute/$(VERSTRING) - @tar --exclude=.svn --exclude=*CVS* -cvjf distribute/$(VERSTRING)/libfat-src-$(VERSTRING).tar.bz2 \ - source include Makefile \ - nds/Makefile \ - gba/Makefile \ - libogc/Makefile - -dist: dist-bin dist-src - -distribute/$(VERSTRING): - @[ -d $@ ] || mkdir -p $@ - -include/libfatversion.h : Makefile - @echo "#ifndef __LIBFATVERSION_H__" > $@ - @echo "#define __LIBFATVERSION_H__" >> $@ - @echo >> $@ - @echo "#define _LIBFAT_MAJOR_ $(LIBFAT_MAJOR)" >> $@ - @echo "#define _LIBFAT_MINOR_ $(LIBFAT_MINOR)" >> $@ - @echo "#define _LIBFAT_PATCH_ $(LIBFAT_PATCH)" >> $@ - @echo >> $@ - @echo '#define _LIBFAT_STRING "libFAT Release '$(LIBFAT_MAJOR).$(LIBFAT_MINOR).$(LIBFAT_PATCH)'"' >> $@ - @echo >> $@ - @echo "#endif // __LIBFATVERSION_H__" >> $@ - -install: nds-install gba-install ogc-install - -nds-install: nds-release - $(MAKE) -C nds install - -gba-install: gba-release - $(MAKE) -C gba install - -ogc-install: cube-release wii-release - $(MAKE) -C libogc install diff --git a/cube/libfat-frag/src/gba/Makefile b/cube/libfat-frag/src/gba/Makefile deleted file mode 100644 index d9c60392..00000000 --- a/cube/libfat-frag/src/gba/Makefile +++ /dev/null @@ -1,160 +0,0 @@ -#--------------------------------------------------------------------------------- -.SUFFIXES: -#--------------------------------------------------------------------------------- -ifeq ($(strip $(DEVKITARM)),) -$(error "Please set DEVKITARM in your environment. export DEVKITARM=devkitARM) -endif - -include $(DEVKITARM)/gba_rules - - -#--------------------------------------------------------------------------------- -# BUILD is the directory where object files & intermediate files will be placed -# SOURCES is a list of directories containing source code -# INCLUDES is a list of directories containing extra header files -# DATA is a list of directories containing binary files -# LIB is where the built library will be placed -# all directories are relative to this makefile -#--------------------------------------------------------------------------------- -BUILD ?= release -SOURCES := ../source -INCLUDES := ../include -DATA := -LIB := $(TOPDIR)/gba/lib - -#--------------------------------------------------------------------------------- -# options for code generation -#--------------------------------------------------------------------------------- -ARCH := -mthumb -mthumb-interwork - -CFLAGS := -g -Wall -O2\ - -mcpu=arm7tdmi -mtune=arm7tdmi\ - -fomit-frame-pointer\ - -ffast-math \ - $(ARCH) - -CFLAGS += $(INCLUDE) -DGBA -CXXFLAGS := $(CFLAGS) - -ASFLAGS := -g $(ARCH) - -ifneq ($(BUILD),debug) -export GBABIN := $(LIB)/libfat.a -else -export GBABIN := $(LIB)/libfatd.a -CFLAGS += -DFAT_DEBUG -endif - - -#--------------------------------------------------------------------------------- -# any extra libraries we wish to link with the project -#--------------------------------------------------------------------------------- -LIBS := -#-lnds9 - -#--------------------------------------------------------------------------------- -# list of directories containing libraries, this must be the top level containing -# include and lib -#--------------------------------------------------------------------------------- -LIBDIRS := $(LIBGBA) - -#--------------------------------------------------------------------------------- -# no real need to edit anything past this point unless you need to add additional -# rules for different file extensions -#--------------------------------------------------------------------------------- -ifneq ($(BUILD),$(notdir $(CURDIR))) -#--------------------------------------------------------------------------------- - -export TOPDIR ?= $(CURDIR)/.. - -export DEPSDIR := $(CURDIR)/$(BUILD) - -export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ - $(foreach dir,$(DATA),$(CURDIR)/$(dir)) - -export CC := $(PREFIX)gcc -export CXX := $(PREFIX)g++ -export AR := $(PREFIX)ar -export OBJCOPY := $(PREFIX)objcopy - -CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) -CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) -SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) -BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) - -#--------------------------------------------------------------------------------- -# use CXX for linking C++ projects, CC for standard C -#--------------------------------------------------------------------------------- -ifeq ($(strip $(CPPFILES)),) -#--------------------------------------------------------------------------------- - export LD := $(CC) -#--------------------------------------------------------------------------------- -else -#--------------------------------------------------------------------------------- - export LD := $(CXX) -#--------------------------------------------------------------------------------- -endif -#--------------------------------------------------------------------------------- - -export OFILES := $(addsuffix .o,$(BINFILES)) \ - $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o) - -export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ - $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ - $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ - -I$(CURDIR)/$(BUILD) - -export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) - -.PHONY: $(BUILD) clean - -#--------------------------------------------------------------------------------- -$(BUILD): - @[ -d $@ ] || mkdir -p $@ - @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile - -#--------------------------------------------------------------------------------- -clean: - @echo clean ... - @rm -fr debug release $(LIB) - -all: $(GBABIN) - -dist-bin: - @tar --exclude=.svn --exclude=*CVS* -cvjf $(TOPDIR)/distribute/$(VERSTRING)/libfat-gba-$(VERSTRING).tar.bz2 include lib - -install: - cp lib/libfat.a $(DEVKITPRO)/libgba/lib - cp include/fat.h $(DEVKITPRO)/libgba/include - -#--------------------------------------------------------------------------------- -else - -DEPENDS := $(OFILES:.o=.d) - -#--------------------------------------------------------------------------------- -# main targets -#--------------------------------------------------------------------------------- -$(GBABIN) : $(OFILES) $(LIB) - @rm -f "$(GBABIN)" - @$(AR) rcs "$(GBABIN)" $(OFILES) - @echo built ... $(notdir $@) - -$(LIB): - mkdir $(LIB) - -#--------------------------------------------------------------------------------- -# you need a rule like this for each extension you use as binary data -#--------------------------------------------------------------------------------- -%.bin.o : %.bin -#--------------------------------------------------------------------------------- - @echo $(notdir $<) - @$(bin2o) - - --include $(DEPENDS) - -#--------------------------------------------------------------------------------------- -endif -#--------------------------------------------------------------------------------------- - diff --git a/cube/libfat-frag/src/gba/include/fat.h b/cube/libfat-frag/src/gba/include/fat.h deleted file mode 100644 index b0a9b0dd..00000000 --- a/cube/libfat-frag/src/gba/include/fat.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - fat.h - Simple functionality for startup, mounting and unmounting of FAT-based devices. - - Copyright (c) 2006 Michael "Chishm" Chisholm - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#ifndef _LIBFAT_H -#define _LIBFAT_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include "disc_io.h" - -/* -Initialise any inserted block-devices. -Add the fat device driver to the devoptab, making it available for standard file functions. -cacheSize: The number of pages to allocate for each inserted block-device -setAsDefaultDevice: if true, make this the default device driver for file operations -*/ -extern bool fatInit (uint32_t cacheSize, bool setAsDefaultDevice); - -/* -Calls fatInit with setAsDefaultDevice = true and cacheSize optimised for the host system. -*/ -extern bool fatInitDefault (void); - -/* -Mount the device pointed to by interface, and set up a devoptab entry for it as "name:". -You can then access the filesystem using "name:/". -This will mount the active partition or the first valid partition on the disc, -and will use a cache size optimized for the host system. -*/ -extern bool fatMountSimple (const char* name, const DISC_INTERFACE* interface); - -/* -Mount the device pointed to by interface, and set up a devoptab entry for it as "name:". -You can then access the filesystem using "name:/". -If startSector = 0, it will mount the active partition of the first valid partition on -the disc. Otherwise it will try to mount the partition starting at startSector. -cacheSize specifies the number of pages to allocate for the cache. -This will not startup the disc, so you need to call interface->startup(); first. -*/ -extern bool fatMount (const char* name, const DISC_INTERFACE* interface, sec_t startSector, uint32_t cacheSize, uint32_t SectorsPerPage); - -/* -Unmount the partition specified by name. -If there are open files, it will attempt to synchronise them to disc. -*/ -extern void fatUnmount (const char* name); - -#ifdef __cplusplus -} -#endif - -#endif // _LIBFAT_H diff --git a/cube/libfat-frag/src/include/fat.h b/cube/libfat-frag/src/include/fat.h deleted file mode 100644 index 03e83a21..00000000 --- a/cube/libfat-frag/src/include/fat.h +++ /dev/null @@ -1,122 +0,0 @@ -/* - fat.h - Simple functionality for startup, mounting and unmounting of FAT-based devices. - - Copyright (c) 2006 - 2012 - Michael "Chishm" Chisholm - Dave "WinterMute" Murphy - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#ifndef _LIBFAT_H -#define _LIBFAT_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include "libfatversion.h" - -// When compiling for NDS, make sure NDS is defined -#ifndef NDS - #if defined ARM9 || defined ARM7 - #define NDS - #endif -#endif - -#include - -#if defined(__gamecube__) || defined (__wii__) -# include -#else -# ifdef NDS -# include -# else -# include -# endif -#endif - -/* -Initialise any inserted block-devices. -Add the fat device driver to the devoptab, making it available for standard file functions. -cacheSize: The number of pages to allocate for each inserted block-device -setAsDefaultDevice: if true, make this the default device driver for file operations -*/ -extern bool fatInit (uint32_t cacheSize, bool setAsDefaultDevice); - -/* -Calls fatInit with setAsDefaultDevice = true and cacheSize optimised for the host system. -*/ -extern bool fatInitDefault (void); - -/* -Mount the device pointed to by interface, and set up a devoptab entry for it as "name:". -You can then access the filesystem using "name:/". -This will mount the active partition or the first valid partition on the disc, -and will use a cache size optimized for the host system. -*/ -extern bool fatMountSimple (const char* name, const DISC_INTERFACE* interface); - -/* -Mount the device pointed to by interface, and set up a devoptab entry for it as "name:". -You can then access the filesystem using "name:/". -If startSector = 0, it will mount the active partition of the first valid partition on -the disc. Otherwise it will try to mount the partition starting at startSector. -cacheSize specifies the number of pages to allocate for the cache. -This will not startup the disc, so you need to call interface->startup(); first. -*/ -extern bool fatMount (const char* name, const DISC_INTERFACE* interface, sec_t startSector, uint32_t cacheSize, uint32_t SectorsPerPage); - -/* -Unmount the partition specified by name. -If there are open files, it will attempt to synchronise them to disc. -*/ -extern void fatUnmount (const char* name); - -/* -Get Volume Label -*/ -extern void fatGetVolumeLabel (const char* name, char *label); - -// File attributes -#define ATTR_ARCHIVE 0x20 // Archive -#define ATTR_DIRECTORY 0x10 // Directory -#define ATTR_VOLUME 0x08 // Volume -#define ATTR_SYSTEM 0x04 // System -#define ATTR_HIDDEN 0x02 // Hidden -#define ATTR_READONLY 0x01 // Read only - -/* -Methods to modify DOS File Attributes -*/ -int FAT_getAttr(const char *file); -int FAT_setAttr(const char *file, int attr ); - -#define LIBFAT_FEOS_MULTICWD - -#ifdef __cplusplus -} -#endif - -#endif // _LIBFAT_H diff --git a/cube/libfat-frag/src/include/libfatversion.h b/cube/libfat-frag/src/include/libfatversion.h deleted file mode 100644 index 791c2cd7..00000000 --- a/cube/libfat-frag/src/include/libfatversion.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef __LIBFATVERSION_H__ -#define __LIBFATVERSION_H__ - -#define _LIBFAT_MAJOR_ 1 -#define _LIBFAT_MINOR_ 0 -#define _LIBFAT_PATCH_ 12 - -#define _LIBFAT_STRING "libFAT Release 1.0.12" - -#endif // __LIBFATVERSION_H__ diff --git a/cube/libfat-frag/src/libogc/Makefile b/cube/libfat-frag/src/libogc/Makefile deleted file mode 100644 index ded05d21..00000000 --- a/cube/libfat-frag/src/libogc/Makefile +++ /dev/null @@ -1,134 +0,0 @@ -#--------------------------------------------------------------------------------- -.SUFFIXES: -#--------------------------------------------------------------------------------- -ifeq ($(strip $(DEVKITPPC)),) -$(error "Please set DEVKITPPC in your environment. export DEVKITPPC=devkitPPC) -endif - -ifeq ($(PLATFORM),wii) -include $(DEVKITPPC)/wii_rules -endif - -ifeq ($(PLATFORM),cube) -include $(DEVKITPPC)/gamecube_rules -endif - -#--------------------------------------------------------------------------------- -# BUILD is the directory where object files & intermediate files will be placed -# SOURCES is a list of directories containing source code -# INCLUDES is a list of directories containing extra header files -# DATA is a list of directories containing binary files -# LIBDIR is where the built library will be placed -# all directories are relative to this makefile -#--------------------------------------------------------------------------------- -BUILD ?= wii_release -SOURCES := ../source -INCLUDES := ../include -DATA := -LIBDIR := $(TOPDIR)/libogc/lib - -#--------------------------------------------------------------------------------- -# options for code generation -#--------------------------------------------------------------------------------- -CFLAGS = -g -Os -Wall $(MACHDEP) $(INCLUDE) -CXXFLAGS = $(CFLAGS) - -ASFLAGS := -g - -ifneq ($(BUILD),debug) -export CUBEBIN := $(LIBDIR)/$(PLATFORM)/libfat.a -else -export CUBEBIN := $(LIBDIR)/$(PLATFORM)/libfatd.a -CFLAGS += -DFAT_DEBUG -endif - -#--------------------------------------------------------------------------------- -# any extra libraries we wish to link with the project -#--------------------------------------------------------------------------------- -LIBS := - -#--------------------------------------------------------------------------------- -# list of directories containing libraries, this must be the top level containing -# include and lib -#--------------------------------------------------------------------------------- -LIBDIRS := - -#--------------------------------------------------------------------------------- -# no real need to edit anything past this point unless you need to add additional -# rules for different file extensions -#--------------------------------------------------------------------------------- -ifneq ($(BUILD),$(notdir $(CURDIR))) -#--------------------------------------------------------------------------------- - -export TOPDIR ?= $(CURDIR)/.. - - -export DEPSDIR := $(CURDIR)/$(BUILD) - -export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ - $(foreach dir,$(DATA),$(CURDIR)/$(dir)) - -CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) -CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) -SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) -BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) - - -export OFILES := $(addsuffix .o,$(BINFILES)) \ - $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o) - -export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ - $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ - $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ - -I$(CURDIR)/$(BUILD) \ - -I$(LIBOGC_INC) - -export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) \ - -L$(LIBOGC_LIB) - -.PHONY: $(BUILD) clean - -#--------------------------------------------------------------------------------- -$(BUILD): - @[ -d $@ ] || mkdir -p $@ - @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile - -#--------------------------------------------------------------------------------- -clean: - @echo clean ... - @rm -fr wii_debug wii_release cube_debug cube_release $(LIBDIR) include - -all: $(CUBEBIN) - -dist-bin: - @mkdir -p include - @cp $(TOPDIR)/include/fat.h $(TOPDIR)/include/libfatversion.h include - @tar --exclude=.svn --exclude=*CVS* -cvjf $(TOPDIR)/distribute/$(VERSTRING)/libfat-ogc-$(VERSTRING).tar.bz2 include lib - -install: - @cp lib/wii/libfat.a $(DEVKITPRO)/libogc/lib/wii - @cp lib/cube/libfat.a $(DEVKITPRO)/libogc/lib/cube - @cp $(TOPDIR)/include/fat.h $(TOPDIR)/include/libfatversion.h $(DEVKITPRO)/libogc/include - -#--------------------------------------------------------------------------------- -else - -DEPENDS := $(OFILES:.o=.d) - -#--------------------------------------------------------------------------------- -# main targets -#--------------------------------------------------------------------------------- -$(CUBEBIN) : $(OFILES) $(LIBDIR)/$(PLATFORM) - @rm -f "$(CUBEBIN)" - @$(AR) rcs "$(CUBEBIN)" $(OFILES) - @echo built ... $(notdir $@) - -$(LIBDIR)/$(PLATFORM): - mkdir -p $(LIBDIR)/$(PLATFORM) - --include $(DEPENDS) - -#--------------------------------------------------------------------------------------- -endif -#--------------------------------------------------------------------------------------- - diff --git a/cube/libfat-frag/src/libogc/include/fat.h b/cube/libfat-frag/src/libogc/include/fat.h deleted file mode 100644 index 31efbe02..00000000 --- a/cube/libfat-frag/src/libogc/include/fat.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - fat.h - Simple functionality for startup, mounting and unmounting of FAT-based devices. - - Copyright (c) 2006 Michael "Chishm" Chisholm - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#ifndef _LIBFAT_H -#define _LIBFAT_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include - -/* -Initialise any inserted block-devices. -Add the fat device driver to the devoptab, making it available for standard file functions. -cacheSize: The number of pages to allocate for each inserted block-device -setAsDefaultDevice: if true, make this the default device driver for file operations -*/ -extern bool fatInit (uint32_t cacheSize, bool setAsDefaultDevice); - -/* -Calls fatInit with setAsDefaultDevice = true and cacheSize optimised for the host system. -*/ -extern bool fatInitDefault (void); - -/* -Mount the device pointed to by interface, and set up a devoptab entry for it as "name:". -You can then access the filesystem using "name:/". -This will mount the active partition or the first valid partition on the disc, -and will use a cache size optimized for the host system. -*/ -extern bool fatMountSimple (const char* name, const DISC_INTERFACE* interface); - -/* -Mount the device pointed to by interface, and set up a devoptab entry for it as "name:". -You can then access the filesystem using "name:/". -If startSector = 0, it will mount the active partition of the first valid partition on -the disc. Otherwise it will try to mount the partition starting at startSector. -cacheSize specifies the number of pages to allocate for the cache. -This will not startup the disc, so you need to call interface->startup(); first. -*/ -extern bool fatMount (const char* name, const DISC_INTERFACE* interface, sec_t startSector, uint32_t cacheSize, uint32_t SectorsPerPage); - -/* -Unmount the partition specified by name. -If there are open files, it will attempt to synchronise them to disc. -*/ -extern void fatUnmount (const char* name); - -/* -Get Volume Label -*/ -extern void fatGetVolumeLabel (const char* name, char *label); - -#ifdef __cplusplus -} -#endif - -#endif // _LIBFAT_H diff --git a/cube/libfat-frag/src/nds/Makefile b/cube/libfat-frag/src/nds/Makefile deleted file mode 100644 index d9135c67..00000000 --- a/cube/libfat-frag/src/nds/Makefile +++ /dev/null @@ -1,131 +0,0 @@ -#--------------------------------------------------------------------------------- -.SUFFIXES: -#--------------------------------------------------------------------------------- -ifeq ($(strip $(DEVKITARM)),) -$(error "Please set DEVKITARM in your environment. export DEVKITARM=devkitARM) -endif - -include $(DEVKITARM)/ds_rules - -#--------------------------------------------------------------------------------- -# BUILD is the directory where object files & intermediate files will be placed -# SOURCES is a list of directories containing source code -# INCLUDES is a list of directories containing extra header files -# DATA is a list of directories containing binary files -# LIB is where the built library will be placed -# all directories are relative to this makefile -#--------------------------------------------------------------------------------- -BUILD ?= release -SOURCES := ../source source -INCLUDES := ../include -DATA := -LIB := $(TOPDIR)/nds/lib - -#--------------------------------------------------------------------------------- -# options for code generation -#--------------------------------------------------------------------------------- -ARCH := -mthumb -mthumb-interwork - -CFLAGS := -g -Wall -O2\ - -march=armv5te -mtune=arm946e-s -fomit-frame-pointer\ - -ffast-math \ - $(ARCH) - -CFLAGS += $(INCLUDE) -DARM9 -DNDS -CXXFLAGS := $(CFLAGS) - -ASFLAGS := -g $(ARCH) - -ifneq ($(BUILD),debug) -export ARM9BIN := $(LIB)/libfat.a -else -export ARM9BIN := $(LIB)/libfatd.a -CFLAGS += -DFAT_DEBUG -endif - -#--------------------------------------------------------------------------------- -# any extra libraries we wish to link with the project -#--------------------------------------------------------------------------------- -LIBS := - -#--------------------------------------------------------------------------------- -# list of directories containing libraries, this must be the top level containing -# include and lib -#--------------------------------------------------------------------------------- -LIBDIRS := $(LIBNDS) - -#--------------------------------------------------------------------------------- -# no real need to edit anything past this point unless you need to add additional -# rules for different file extensions -#--------------------------------------------------------------------------------- -ifneq ($(BUILD),$(notdir $(CURDIR))) -#--------------------------------------------------------------------------------- - -export TOPDIR ?= $(CURDIR)/.. - - -export DEPSDIR := $(CURDIR)/$(BUILD) - -export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ - $(foreach dir,$(DATA),$(CURDIR)/$(dir)) - -CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) -CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) -SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) -BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) - - -export OFILES := $(addsuffix .o,$(BINFILES)) \ - $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o) - -export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ - $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ - $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ - -I$(CURDIR)/$(BUILD) - -export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) - -.PHONY: $(BUILD) clean - -#--------------------------------------------------------------------------------- -$(BUILD): - @[ -d $@ ] || mkdir -p $@ - @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile - -#--------------------------------------------------------------------------------- -clean: - @echo clean ... - @rm -fr debug release $(LIB) - -all: $(ARM9BIN) - -dist-bin: - @tar --exclude=.svn --exclude=*CVS* -cvjf $(TOPDIR)/distribute/$(VERSTRING)/libfat-nds-$(VERSTRING).tar.bz2 include lib - -install: - cp lib/libfat.a $(DEVKITPRO)/libnds/lib - cp include/fat.h $(DEVKITPRO)/libnds/include - -#--------------------------------------------------------------------------------- -else - -DEPENDS := $(OFILES:.o=.d) - -#--------------------------------------------------------------------------------- -# main targets -#--------------------------------------------------------------------------------- -$(ARM9BIN) : $(OFILES) $(LIB) - @rm -f "$(ARM9BIN)" - @$(AR) rcs "$(ARM9BIN)" $(OFILES) - @echo built ... $(notdir $@) - -$(LIB): - mkdir $(LIB) - - --include $(DEPENDS) - -#--------------------------------------------------------------------------------------- -endif -#--------------------------------------------------------------------------------------- - diff --git a/cube/libfat-frag/src/nds/include/fat.h b/cube/libfat-frag/src/nds/include/fat.h deleted file mode 100644 index 5272b807..00000000 --- a/cube/libfat-frag/src/nds/include/fat.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - fat.h - Simple functionality for startup, mounting and unmounting of FAT-based devices. - - Copyright (c) 2006 Michael "Chishm" Chisholm - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#ifndef _LIBFAT_H -#define _LIBFAT_H - -#ifdef __cplusplus -extern "C" { -#endif - -// When compiling for NDS, make sure NDS is defined -#ifndef NDS -#define NDS -#endif - -#include -#include "nds/disc_io.h" - -/* -Initialise any inserted block-devices. -Add the fat device driver to the devoptab, making it available for standard file functions. -cacheSize: The number of pages to allocate for each inserted block-device -setAsDefaultDevice: if true, make this the default device driver for file operations -*/ -extern bool fatInit (uint32_t cacheSize, bool setAsDefaultDevice); - -/* -Calls fatInit with setAsDefaultDevice = true and cacheSize optimised for the host system. -*/ -extern bool fatInitDefault (void); - -/* -Mount the device pointed to by interface, and set up a devoptab entry for it as "name:". -You can then access the filesystem using "name:/". -This will mount the active partition or the first valid partition on the disc, -and will use a cache size optimized for the host system. -*/ -extern bool fatMountSimple (const char* name, const DISC_INTERFACE* interface); - -/* -Mount the device pointed to by interface, and set up a devoptab entry for it as "name:". -You can then access the filesystem using "name:/". -If startSector = 0, it will mount the active partition of the first valid partition on -the disc. Otherwise it will try to mount the partition starting at startSector. -cacheSize specifies the number of pages to allocate for the cache. -This will not startup the disc, so you need to call interface->startup(); first. -*/ -extern bool fatMount (const char* name, const DISC_INTERFACE* interface, sec_t startSector, uint32_t cacheSize, uint32_t SectorsPerPage); - -/* -Unmount the partition specified by name. -If there are open files, it will attempt to synchronise them to disc. -*/ -extern void fatUnmount (const char* name); - -#ifdef __cplusplus -} -#endif - -#endif // _LIBFAT_H diff --git a/cube/libfat-frag/src/source/bit_ops.h b/cube/libfat-frag/src/source/bit_ops.h deleted file mode 100644 index 762be0b3..00000000 --- a/cube/libfat-frag/src/source/bit_ops.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - bit_ops.h - Functions for dealing with conversion of data between types - - Copyright (c) 2006 Michael "Chishm" Chisholm - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef _BIT_OPS_H -#define _BIT_OPS_H - -#include - -/*----------------------------------------------------------------- -Functions to deal with little endian values stored in uint8_t arrays ------------------------------------------------------------------*/ -static inline uint16_t u8array_to_u16 (const uint8_t* item, int offset) { - return ( item[offset] | (item[offset + 1] << 8)); -} - -static inline uint32_t u8array_to_u32 (const uint8_t* item, int offset) { - return ( item[offset] | (item[offset + 1] << 8) | (item[offset + 2] << 16) | (item[offset + 3] << 24)); -} - -static inline void u16_to_u8array (uint8_t* item, int offset, uint16_t value) { - item[offset] = (uint8_t) value; - item[offset + 1] = (uint8_t)(value >> 8); -} - -static inline void u32_to_u8array (uint8_t* item, int offset, uint32_t value) { - item[offset] = (uint8_t) value; - item[offset + 1] = (uint8_t)(value >> 8); - item[offset + 2] = (uint8_t)(value >> 16); - item[offset + 3] = (uint8_t)(value >> 24); -} - -#endif // _BIT_OPS_H diff --git a/cube/libfat-frag/src/source/cache.c b/cube/libfat-frag/src/source/cache.c deleted file mode 100644 index 07576b9c..00000000 --- a/cube/libfat-frag/src/source/cache.c +++ /dev/null @@ -1,323 +0,0 @@ -/* - cache.c - The cache is not visible to the user. It should be flushed - when any file is closed or changes are made to the filesystem. - - This cache implements a least-used-page replacement policy. This will - distribute sectors evenly over the pages, so if less than the maximum - pages are used at once, they should all eventually remain in the cache. - This also has the benefit of throwing out old sectors, so as not to keep - too many stale pages around. - - Copyright (c) 2006 Michael "Chishm" Chisholm - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include -#include - -#include "common.h" -#include "cache.h" -#include "disc.h" - -#include "mem_allocate.h" -#include "bit_ops.h" -#include "file_allocation_table.h" - -#define CACHE_FREE UINT_MAX - -CACHE* _FAT_cache_constructor (unsigned int numberOfPages, unsigned int sectorsPerPage, const DISC_INTERFACE* discInterface, sec_t endOfPartition, unsigned int bytesPerSector) { - CACHE* cache; - unsigned int i; - CACHE_ENTRY* cacheEntries; - - if (numberOfPages < 2) { - numberOfPages = 2; - } - - if (sectorsPerPage < 8) { - sectorsPerPage = 8; - } - - cache = (CACHE*) _FAT_mem_allocate (sizeof(CACHE)); - if (cache == NULL) { - return NULL; - } - - cache->disc = discInterface; - cache->endOfPartition = endOfPartition; - cache->numberOfPages = numberOfPages; - cache->sectorsPerPage = sectorsPerPage; - cache->bytesPerSector = bytesPerSector; - - - cacheEntries = (CACHE_ENTRY*) _FAT_mem_allocate ( sizeof(CACHE_ENTRY) * numberOfPages); - if (cacheEntries == NULL) { - _FAT_mem_free (cache); - return NULL; - } - - for (i = 0; i < numberOfPages; i++) { - cacheEntries[i].sector = CACHE_FREE; - cacheEntries[i].count = 0; - cacheEntries[i].last_access = 0; - cacheEntries[i].dirty = false; - cacheEntries[i].cache = (uint8_t*) _FAT_mem_align ( sectorsPerPage * bytesPerSector ); - } - - cache->cacheEntries = cacheEntries; - - return cache; -} - -void _FAT_cache_destructor (CACHE* cache) { - unsigned int i; - // Clear out cache before destroying it - _FAT_cache_flush(cache); - - // Free memory in reverse allocation order - for (i = 0; i < cache->numberOfPages; i++) { - _FAT_mem_free (cache->cacheEntries[i].cache); - } - _FAT_mem_free (cache->cacheEntries); - _FAT_mem_free (cache); -} - - -static u32 accessCounter = 0; - -static u32 accessTime(){ - accessCounter++; - return accessCounter; -} - - -static CACHE_ENTRY* _FAT_cache_getPage(CACHE *cache,sec_t sector) -{ - unsigned int i; - CACHE_ENTRY* cacheEntries = cache->cacheEntries; - unsigned int numberOfPages = cache->numberOfPages; - unsigned int sectorsPerPage = cache->sectorsPerPage; - - bool foundFree = false; - unsigned int oldUsed = 0; - unsigned int oldAccess = UINT_MAX; - - for(i=0;i=cacheEntries[i].sector && sector<(cacheEntries[i].sector + cacheEntries[i].count)) { - cacheEntries[i].last_access = accessTime(); - return &(cacheEntries[i]); - } - - if(foundFree==false && (cacheEntries[i].sector==CACHE_FREE || cacheEntries[i].last_accessdisc,cacheEntries[oldUsed].sector,cacheEntries[oldUsed].count,cacheEntries[oldUsed].cache)) return NULL; - cacheEntries[oldUsed].dirty = false; - } - - sector = (sector/sectorsPerPage)*sectorsPerPage; // align base sector to page size - sec_t next_page = sector + sectorsPerPage; - if(next_page > cache->endOfPartition) next_page = cache->endOfPartition; - - if(!_FAT_disc_readSectors(cache->disc,sector,next_page-sector,cacheEntries[oldUsed].cache)) return NULL; - - cacheEntries[oldUsed].sector = sector; - cacheEntries[oldUsed].count = next_page-sector; - cacheEntries[oldUsed].last_access = accessTime(); - - return &(cacheEntries[oldUsed]); -} - -bool _FAT_cache_readSectors(CACHE *cache,sec_t sector,sec_t numSectors,void *buffer) -{ - sec_t sec; - sec_t secs_to_read; - CACHE_ENTRY *entry; - uint8_t *dest = (uint8_t *)buffer; - - while(numSectors>0) { - entry = _FAT_cache_getPage(cache,sector); - if(entry==NULL) return false; - - sec = sector - entry->sector; - secs_to_read = entry->count - sec; - if(secs_to_read>numSectors) secs_to_read = numSectors; - - memcpy(dest,entry->cache + (sec*cache->bytesPerSector),(secs_to_read*cache->bytesPerSector)); - - dest += (secs_to_read*cache->bytesPerSector); - sector += secs_to_read; - numSectors -= secs_to_read; - } - - return true; -} - -/* -Reads some data from a cache page, determined by the sector number -*/ -bool _FAT_cache_readPartialSector (CACHE* cache, void* buffer, sec_t sector, unsigned int offset, size_t size) -{ - sec_t sec; - CACHE_ENTRY *entry; - - if (offset + size > cache->bytesPerSector) return false; - - entry = _FAT_cache_getPage(cache,sector); - if(entry==NULL) return false; - - sec = sector - entry->sector; - memcpy(buffer,entry->cache + ((sec*cache->bytesPerSector) + offset),size); - - return true; -} - -bool _FAT_cache_readLittleEndianValue (CACHE* cache, uint32_t *value, sec_t sector, unsigned int offset, int num_bytes) { - uint8_t buf[4]; - if (!_FAT_cache_readPartialSector(cache, buf, sector, offset, num_bytes)) return false; - - switch(num_bytes) { - case 1: *value = buf[0]; break; - case 2: *value = u8array_to_u16(buf,0); break; - case 4: *value = u8array_to_u32(buf,0); break; - default: return false; - } - return true; -} - -/* -Writes some data to a cache page, making sure it is loaded into memory first. -*/ -bool _FAT_cache_writePartialSector (CACHE* cache, const void* buffer, sec_t sector, unsigned int offset, size_t size) -{ - sec_t sec; - CACHE_ENTRY *entry; - - if (offset + size > cache->bytesPerSector) return false; - - entry = _FAT_cache_getPage(cache,sector); - if(entry==NULL) return false; - - sec = sector - entry->sector; - memcpy(entry->cache + ((sec*cache->bytesPerSector) + offset),buffer,size); - - entry->dirty = true; - return true; -} - -bool _FAT_cache_writeLittleEndianValue (CACHE* cache, const uint32_t value, sec_t sector, unsigned int offset, int size) { - uint8_t buf[4] = {0, 0, 0, 0}; - - switch(size) { - case 1: buf[0] = value; break; - case 2: u16_to_u8array(buf, 0, value); break; - case 4: u32_to_u8array(buf, 0, value); break; - default: return false; - } - - return _FAT_cache_writePartialSector(cache, buf, sector, offset, size); -} - -/* -Writes some data to a cache page, zeroing out the page first -*/ -bool _FAT_cache_eraseWritePartialSector (CACHE* cache, const void* buffer, sec_t sector, unsigned int offset, size_t size) -{ - sec_t sec; - CACHE_ENTRY *entry; - - if (offset + size > cache->bytesPerSector) return false; - - entry = _FAT_cache_getPage(cache,sector); - if(entry==NULL) return false; - - sec = sector - entry->sector; - memset(entry->cache + (sec*cache->bytesPerSector),0,cache->bytesPerSector); - memcpy(entry->cache + ((sec*cache->bytesPerSector) + offset),buffer,size); - - entry->dirty = true; - return true; -} - - -bool _FAT_cache_writeSectors (CACHE* cache, sec_t sector, sec_t numSectors, const void* buffer) -{ - sec_t sec; - sec_t secs_to_write; - CACHE_ENTRY* entry; - const uint8_t *src = (const uint8_t *)buffer; - - while(numSectors>0) - { - entry = _FAT_cache_getPage(cache,sector); - if(entry==NULL) return false; - - sec = sector - entry->sector; - secs_to_write = entry->count - sec; - if(secs_to_write>numSectors) secs_to_write = numSectors; - - memcpy(entry->cache + (sec*cache->bytesPerSector),src,(secs_to_write*cache->bytesPerSector)); - - src += (secs_to_write*cache->bytesPerSector); - sector += secs_to_write; - numSectors -= secs_to_write; - - entry->dirty = true; - } - return true; -} - -/* -Flushes all dirty pages to disc, clearing the dirty flag. -*/ -bool _FAT_cache_flush (CACHE* cache) { - unsigned int i; - - for (i = 0; i < cache->numberOfPages; i++) { - if (cache->cacheEntries[i].dirty) { - if (!_FAT_disc_writeSectors (cache->disc, cache->cacheEntries[i].sector, cache->cacheEntries[i].count, cache->cacheEntries[i].cache)) { - return false; - } - } - cache->cacheEntries[i].dirty = false; - } - - return true; -} - -void _FAT_cache_invalidate (CACHE* cache) { - unsigned int i; - _FAT_cache_flush(cache); - for (i = 0; i < cache->numberOfPages; i++) { - cache->cacheEntries[i].sector = CACHE_FREE; - cache->cacheEntries[i].last_access = 0; - cache->cacheEntries[i].count = 0; - cache->cacheEntries[i].dirty = false; - } -} diff --git a/cube/libfat-frag/src/source/cache.h b/cube/libfat-frag/src/source/cache.h deleted file mode 100644 index 07bb14c2..00000000 --- a/cube/libfat-frag/src/source/cache.h +++ /dev/null @@ -1,128 +0,0 @@ -/* - cache.h - The cache is not visible to the user. It should be flushed - when any file is closed or changes are made to the filesystem. - - This cache implements a least-used-page replacement policy. This will - distribute sectors evenly over the pages, so if less than the maximum - pages are used at once, they should all eventually remain in the cache. - This also has the benefit of throwing out old sectors, so as not to keep - too many stale pages around. - - Copyright (c) 2006 Michael "Chishm" Chisholm - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef _CACHE_H -#define _CACHE_H - -#include "common.h" -#include "disc.h" - -typedef struct { - sec_t sector; - unsigned int count; - unsigned int last_access; - bool dirty; - uint8_t* cache; -} CACHE_ENTRY; - -typedef struct { - const DISC_INTERFACE* disc; - sec_t endOfPartition; - unsigned int numberOfPages; - unsigned int sectorsPerPage; - unsigned int bytesPerSector; - CACHE_ENTRY* cacheEntries; -} CACHE; - -/* -Read data from a sector in the cache -If the sector is not in the cache, it will be swapped in -offset is the position to start reading from -size is the amount of data to read -Precondition: offset + size <= BYTES_PER_READ -*/ -bool _FAT_cache_readPartialSector (CACHE* cache, void* buffer, sec_t sector, unsigned int offset, size_t size); - -bool _FAT_cache_readLittleEndianValue (CACHE* cache, uint32_t *value, sec_t sector, unsigned int offset, int num_bytes); - -/* -Write data to a sector in the cache -If the sector is not in the cache, it will be swapped in. -When the sector is swapped out, the data will be written to the disc -offset is the position to start writing to -size is the amount of data to write -Precondition: offset + size <= BYTES_PER_READ -*/ -bool _FAT_cache_writePartialSector (CACHE* cache, const void* buffer, sec_t sector, unsigned int offset, size_t size); - -bool _FAT_cache_writeLittleEndianValue (CACHE* cache, const uint32_t value, sec_t sector, unsigned int offset, int num_bytes); - -/* -Write data to a sector in the cache, zeroing the sector first -If the sector is not in the cache, it will be swapped in. -When the sector is swapped out, the data will be written to the disc -offset is the position to start writing to -size is the amount of data to write -Precondition: offset + size <= BYTES_PER_READ -*/ -bool _FAT_cache_eraseWritePartialSector (CACHE* cache, const void* buffer, sec_t sector, unsigned int offset, size_t size); - -/* -Read several sectors from the cache -*/ -bool _FAT_cache_readSectors (CACHE* cache, sec_t sector, sec_t numSectors, void* buffer); - -/* -Read a full sector from the cache -*/ -static inline bool _FAT_cache_readSector (CACHE* cache, void* buffer, sec_t sector) { - return _FAT_cache_readPartialSector (cache, buffer, sector, 0, cache->bytesPerSector); -} - -/* -Write a full sector to the cache -*/ -static inline bool _FAT_cache_writeSector (CACHE* cache, const void* buffer, sec_t sector) { - return _FAT_cache_writePartialSector (cache, buffer, sector, 0, cache->bytesPerSector); -} - -bool _FAT_cache_writeSectors (CACHE* cache, sec_t sector, sec_t numSectors, const void* buffer); - -/* -Write any dirty sectors back to disc and clear out the contents of the cache -*/ -bool _FAT_cache_flush (CACHE* cache); - -/* -Clear out the contents of the cache without writing any dirty sectors first -*/ -void _FAT_cache_invalidate (CACHE* cache); - -CACHE* _FAT_cache_constructor (unsigned int numberOfPages, unsigned int sectorsPerPage, const DISC_INTERFACE* discInterface, sec_t endOfPartition, unsigned int bytesPerSector); - -void _FAT_cache_destructor (CACHE* cache); - -#endif // _CACHE_H - diff --git a/cube/libfat-frag/src/source/common.h b/cube/libfat-frag/src/source/common.h deleted file mode 100644 index c5c56325..00000000 --- a/cube/libfat-frag/src/source/common.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - common.h - Common definitions and included files for the FATlib - - Copyright (c) 2006 Michael "Chishm" Chisholm - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef _COMMON_H -#define _COMMON_H - -#include -#include -#include - -// When compiling for NDS, make sure NDS is defined -#ifndef NDS - #if defined ARM9 || defined ARM7 - #define NDS - #endif -#endif - -// Platform specific includes -#if defined(__gamecube__) || defined (__wii__) - #include - #include - #include -#elif defined(NDS) - #include - #include - #include -#elif defined(GBA) - #include - #include -#endif - -// Platform specific options -#if defined (__wii__) - #define DEFAULT_CACHE_PAGES 4 - #define DEFAULT_SECTORS_PAGE 64 - #define USE_LWP_LOCK - #define USE_RTC_TIME -#elif defined (__gamecube__) - #define DEFAULT_CACHE_PAGES 4 - #define DEFAULT_SECTORS_PAGE 64 - #define USE_LWP_LOCK - #define USE_RTC_TIME -#elif defined (NDS) - #define DEFAULT_CACHE_PAGES 16 - #define DEFAULT_SECTORS_PAGE 8 - #define USE_RTC_TIME -#elif defined (GBA) - #define DEFAULT_CACHE_PAGES 2 - #define DEFAULT_SECTORS_PAGE 8 - #define LIMIT_SECTORS 128 -#endif - -#endif // _COMMON_H diff --git a/cube/libfat-frag/src/source/directory.c b/cube/libfat-frag/src/source/directory.c deleted file mode 100644 index 801ae747..00000000 --- a/cube/libfat-frag/src/source/directory.c +++ /dev/null @@ -1,1130 +0,0 @@ -/* - directory.c - Reading, writing and manipulation of the directory structure on - a FAT partition - - Copyright (c) 2006 Michael "Chishm" Chisholm - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include -#include -#include -#include -#include -#include - -#include "directory.h" -#include "common.h" -#include "partition.h" -#include "file_allocation_table.h" -#include "bit_ops.h" -#include "filetime.h" - -// Directory entry codes -#define DIR_ENTRY_LAST 0x00 -#define DIR_ENTRY_FREE 0xE5 - -#define LAST_LFN_POS (19*13) -#define LAST_LFN_POS_CORRECTION (MAX_LFN_LENGTH-15) - -typedef unsigned short ucs2_t; - -// Long file name directory entry -enum LFN_offset { - LFN_offset_ordinal = 0x00, // Position within LFN - LFN_offset_char0 = 0x01, - LFN_offset_char1 = 0x03, - LFN_offset_char2 = 0x05, - LFN_offset_char3 = 0x07, - LFN_offset_char4 = 0x09, - LFN_offset_flag = 0x0B, // Should be equal to ATTRIB_LFN - LFN_offset_reserved1 = 0x0C, // Always 0x00 - LFN_offset_checkSum = 0x0D, // Checksum of short file name (alias) - LFN_offset_char5 = 0x0E, - LFN_offset_char6 = 0x10, - LFN_offset_char7 = 0x12, - LFN_offset_char8 = 0x14, - LFN_offset_char9 = 0x16, - LFN_offset_char10 = 0x18, - LFN_offset_reserved2 = 0x1A, // Always 0x0000 - LFN_offset_char11 = 0x1C, - LFN_offset_char12 = 0x1E -}; -static const int LFN_offset_table[13]={0x01,0x03,0x05,0x07,0x09,0x0E,0x10,0x12,0x14,0x16,0x18,0x1C,0x1E}; - -#define LFN_END 0x40 -#define LFN_DEL 0x80 - -static const char ILLEGAL_ALIAS_CHARACTERS[] = "\\/:;*?\"<>|&+,=[] "; -static const char ILLEGAL_LFN_CHARACTERS[] = "\\/:*?\"<>|"; - -/* -Returns number of UCS-2 characters needed to encode an LFN -Returns -1 if it is an invalid LFN -*/ -#define ABOVE_UCS_RANGE 0xF0 -static int _FAT_directory_lfnLength (const char* name) { - unsigned int i; - size_t nameLength; - int ucsLength; - const char* tempName = name; - - nameLength = strnlen(name, MAX_FILENAME_LENGTH); - // Make sure the name is short enough to be valid - if ( nameLength >= MAX_FILENAME_LENGTH) { - return -1; - } - // Make sure it doesn't contain any invalid characters - if (strpbrk (name, ILLEGAL_LFN_CHARACTERS) != NULL) { - return -1; - } - // Make sure the name doesn't contain any control codes or codes not representable in UCS-2 - for (i = 0; i < nameLength; i++) { - if (name[i] < 0x20 || name[i] >= ABOVE_UCS_RANGE) { - return -1; - } - } - // Convert to UCS-2 and get the resulting length - ucsLength = mbsrtowcs(NULL, &tempName, MAX_LFN_LENGTH, NULL); - if (ucsLength < 0 || ucsLength >= MAX_LFN_LENGTH) { - return -1; - } - - // Otherwise it is valid - return ucsLength; -} - -/* -Convert a multibyte encoded string into a NUL-terminated UCS-2 string, storing at most len characters -return number of characters stored -*/ -static size_t _FAT_directory_mbstoucs2 (ucs2_t* dst, const char* src, size_t len) { - mbstate_t ps = {0}; - wchar_t tempChar; - int bytes; - size_t count = 0; - - while (count < len-1 && src != '\0') { - bytes = mbrtowc (&tempChar, src, MB_CUR_MAX, &ps); - if (bytes > 0) { - *dst = (ucs2_t)tempChar; - src += bytes; - dst++; - count++; - } else if (bytes == 0) { - break; - } else { - return -1; - } - } - *dst = '\0'; - - return count; -} - -/* -Convert a UCS-2 string into a NUL-terminated multibyte string, storing at most len chars -return number of chars stored, or (size_t)-1 on error -*/ -static size_t _FAT_directory_ucs2tombs (char* dst, const ucs2_t* src, size_t len) { - mbstate_t ps = {0}; - size_t count = 0; - int bytes; - char buff[MB_CUR_MAX]; - int i; - - while (count < len - 1 && *src != '\0') { - bytes = wcrtomb (buff, *src, &ps); - if (bytes < 0) { - return -1; - } - if (count + bytes < len && bytes > 0) { - for (i = 0; i < bytes; i++) { - *dst++ = buff[i]; - } - src++; - count += bytes; - } else { - break; - } - } - *dst = L'\0'; - - return count; -} - -/* -Case-independent comparison of two multibyte encoded strings -*/ -static int _FAT_directory_mbsncasecmp (const char* s1, const char* s2, size_t len1) { - wchar_t wc1, wc2; - mbstate_t ps1 = {0}; - mbstate_t ps2 = {0}; - size_t b1 = 0; - size_t b2 = 0; - - if (len1 == 0) { - return 0; - } - - do { - s1 += b1; - s2 += b2; - b1 = mbrtowc(&wc1, s1, MB_CUR_MAX, &ps1); - b2 = mbrtowc(&wc2, s2, MB_CUR_MAX, &ps2); - if ((int)b1 < 0 || (int)b2 < 0) { - break; - } - len1 -= b1; - } while (len1 > 0 && towlower(wc1) == towlower(wc2) && wc1 != 0); - - return towlower(wc1) - towlower(wc2); -} - - -static bool _FAT_directory_entryGetAlias (const u8* entryData, char* destName) { - char c; - bool caseInfo; - int i = 0; - int j = 0; - - destName[0] = '\0'; - if (entryData[0] != DIR_ENTRY_FREE) { - if (entryData[0] == '.') { - destName[0] = '.'; - if (entryData[1] == '.') { - destName[1] = '.'; - destName[2] = '\0'; - } else { - destName[1] = '\0'; - } - } else { - // Copy the filename from the dirEntry to the string - caseInfo = entryData[DIR_ENTRY_caseInfo] & CASE_LOWER_BASE; - for (i = 0; (i < 8) && (entryData[DIR_ENTRY_name + i] != ' '); i++) { - c = entryData[DIR_ENTRY_name + i]; - destName[i] = (caseInfo ? tolower((unsigned char)c) : c); - } - // Copy the extension from the dirEntry to the string - if (entryData[DIR_ENTRY_extension] != ' ') { - destName[i++] = '.'; - caseInfo = entryData[DIR_ENTRY_caseInfo] & CASE_LOWER_EXT; - for ( j = 0; (j < 3) && (entryData[DIR_ENTRY_extension + j] != ' '); j++) { - c = entryData[DIR_ENTRY_extension + j]; - destName[i++] = (caseInfo ? tolower((unsigned char)c) : c); - } - } - destName[i] = '\0'; - } - } - - return (destName[0] != '\0'); -} - -uint32_t _FAT_directory_entryGetCluster (PARTITION* partition, const uint8_t* entryData) { - if (partition->filesysType == FS_FAT32) { - // Only use high 16 bits of start cluster when we are certain they are correctly defined - return u8array_to_u16(entryData,DIR_ENTRY_cluster) | (u8array_to_u16(entryData, DIR_ENTRY_clusterHigh) << 16); - } else { - return u8array_to_u16(entryData,DIR_ENTRY_cluster); - } -} - -static bool _FAT_directory_incrementDirEntryPosition (PARTITION* partition, DIR_ENTRY_POSITION* entryPosition, bool extendDirectory) { - DIR_ENTRY_POSITION position = *entryPosition; - uint32_t tempCluster; - - // Increment offset, wrapping at the end of a sector - ++ position.offset; - if (position.offset == partition->bytesPerSector / DIR_ENTRY_DATA_SIZE) { - position.offset = 0; - // Increment sector when wrapping - ++ position.sector; - // But wrap at the end of a cluster - if ((position.sector == partition->sectorsPerCluster) && (position.cluster != FAT16_ROOT_DIR_CLUSTER)) { - position.sector = 0; - // Move onto the next cluster, making sure there is another cluster to go to - tempCluster = _FAT_fat_nextCluster(partition, position.cluster); - if (tempCluster == CLUSTER_EOF) { - if (extendDirectory) { - tempCluster = _FAT_fat_linkFreeClusterCleared (partition, position.cluster); - if (!_FAT_fat_isValidCluster(partition, tempCluster)) { - return false; // This will only happen if the disc is full - } - } else { - return false; // Got to the end of the directory, not extending it - } - } - position.cluster = tempCluster; - } else if ((position.cluster == FAT16_ROOT_DIR_CLUSTER) && (position.sector == (partition->dataStart - partition->rootDirStart))) { - return false; // Got to end of root directory, can't extend it - } - } - *entryPosition = position; - return true; -} - -bool _FAT_directory_getNextEntry (PARTITION* partition, DIR_ENTRY* entry) { - DIR_ENTRY_POSITION entryStart; - DIR_ENTRY_POSITION entryEnd; - uint8_t entryData[0x20]; - ucs2_t lfn[MAX_LFN_LENGTH]; - bool notFound, found; - int lfnPos; - uint8_t lfnChkSum, chkSum; - bool lfnExists; - int i; - - lfnChkSum = 0; - - entryStart = entry->dataEnd; - - // Make sure we are using the correct root directory, in case of FAT32 - if (entryStart.cluster == FAT16_ROOT_DIR_CLUSTER) { - entryStart.cluster = partition->rootDirCluster; - } - - entryEnd = entryStart; - - lfnExists = false; - - found = false; - notFound = false; - - while (!found && !notFound) { - if (_FAT_directory_incrementDirEntryPosition (partition, &entryEnd, false) == false) { - notFound = true; - } - - _FAT_cache_readPartialSector (partition->cache, entryData, - _FAT_fat_clusterToSector(partition, entryEnd.cluster) + entryEnd.sector, - entryEnd.offset * DIR_ENTRY_DATA_SIZE, DIR_ENTRY_DATA_SIZE); - - if (entryData[DIR_ENTRY_attributes] == ATTRIB_LFN) { - // It's an LFN - if (entryData[LFN_offset_ordinal] & LFN_DEL) { - lfnExists = false; - } else if (entryData[LFN_offset_ordinal] & LFN_END) { - // Last part of LFN, make sure it isn't deleted using previous if(Thanks MoonLight) - entryStart = entryEnd; // This is the start of a directory entry - lfnExists = true; - lfnPos = (entryData[LFN_offset_ordinal] & ~LFN_END) * 13; - if (lfnPos > MAX_LFN_LENGTH - 1) { - lfnPos = MAX_LFN_LENGTH - 1; - } - lfn[lfnPos] = '\0'; // Set end of lfn to null character - lfnChkSum = entryData[LFN_offset_checkSum]; - } - if (lfnChkSum != entryData[LFN_offset_checkSum]) { - lfnExists = false; - } - if (lfnExists) { - lfnPos = ((entryData[LFN_offset_ordinal] & ~LFN_END) - 1) * 13; - if (lfnPos > LAST_LFN_POS) { - // Force it within the buffer. Will corrupt the filename but prevent buffer overflows - lfnPos = LAST_LFN_POS; - } - for (i = 0; i < 13; i++) { - lfn[lfnPos + i] = entryData[LFN_offset_table[i]] | (entryData[LFN_offset_table[i]+1] << 8); - } - } - } else if (entryData[DIR_ENTRY_attributes] & ATTRIB_VOL) { - // This is a volume name, don't bother with it - } else if (entryData[0] == DIR_ENTRY_LAST) { - notFound = true; - } else if ((entryData[0] != DIR_ENTRY_FREE) && (entryData[0] > 0x20) && !(entryData[DIR_ENTRY_attributes] & ATTRIB_VOL)) { - if (lfnExists) { - // Calculate file checksum - chkSum = 0; - for (i=0; i < 11; i++) { - // NOTE: The operation is an unsigned char rotate right - chkSum = ((chkSum & 1) ? 0x80 : 0) + (chkSum >> 1) + entryData[i]; - } - if (chkSum != lfnChkSum) { - lfnExists = false; - entry->filename[0] = '\0'; - } - } - - if (lfnExists) { - if (_FAT_directory_ucs2tombs (entry->filename, lfn, MAX_FILENAME_LENGTH) == (size_t)-1) { - // Failed to convert the file name to UTF-8. Maybe the wrong locale is set? - return false; - } - } else { - entryStart = entryEnd; - _FAT_directory_entryGetAlias (entryData, entry->filename); - } - found = true; - } - } - - // If no file is found, return false - if (notFound) { - return false; - } else { - // Fill in the directory entry struct - entry->dataStart = entryStart; - entry->dataEnd = entryEnd; - memcpy (entry->entryData, entryData, DIR_ENTRY_DATA_SIZE); - return true; - } -} - -bool _FAT_directory_getFirstEntry (PARTITION* partition, DIR_ENTRY* entry, uint32_t dirCluster) { - entry->dataStart.cluster = dirCluster; - entry->dataStart.sector = 0; - entry->dataStart.offset = -1; // Start before the beginning of the directory - - entry->dataEnd = entry->dataStart; - - return _FAT_directory_getNextEntry (partition, entry); -} - -bool _FAT_directory_getRootEntry (PARTITION* partition, DIR_ENTRY* entry) { - entry->dataStart.cluster = 0; - entry->dataStart.sector = 0; - entry->dataStart.offset = 0; - - entry->dataEnd = entry->dataStart; - - memset (entry->filename, '\0', MAX_FILENAME_LENGTH); - entry->filename[0] = '.'; - - memset (entry->entryData, 0, DIR_ENTRY_DATA_SIZE); - memset (entry->entryData, ' ', 11); - entry->entryData[0] = '.'; - - entry->entryData[DIR_ENTRY_attributes] = ATTRIB_DIR; - - u16_to_u8array (entry->entryData, DIR_ENTRY_cluster, partition->rootDirCluster); - u16_to_u8array (entry->entryData, DIR_ENTRY_clusterHigh, partition->rootDirCluster >> 16); - - return true; -} - -bool _FAT_directory_getVolumeLabel (PARTITION* partition, char *label) { - DIR_ENTRY entry; - DIR_ENTRY_POSITION entryEnd; - uint8_t entryData[DIR_ENTRY_DATA_SIZE]; - int i; - bool end; - - _FAT_directory_getRootEntry(partition, &entry); - - entryEnd = entry.dataEnd; - - // Make sure we are using the correct root directory, in case of FAT32 - if (entryEnd.cluster == FAT16_ROOT_DIR_CLUSTER) { - entryEnd.cluster = partition->rootDirCluster; - } - - label[0]='\0'; - label[11]='\0'; - end = false; - //this entry should be among the first 3 entries in the root directory table, if not, then system can have trouble displaying the right volume label - while(!end) { - if(!_FAT_cache_readPartialSector (partition->cache, entryData, - _FAT_fat_clusterToSector(partition, entryEnd.cluster) + entryEnd.sector, - entryEnd.offset * DIR_ENTRY_DATA_SIZE, DIR_ENTRY_DATA_SIZE)) - { //error reading - return false; - } - - if (entryData[DIR_ENTRY_attributes] == ATTRIB_VOL && entryData[0] != DIR_ENTRY_FREE) { - for (i = 0; i < 11; i++) { - label[i] = entryData[DIR_ENTRY_name + i]; - } - return true; - } else if (entryData[0] == DIR_ENTRY_LAST) { - end = true; - } - - if (_FAT_directory_incrementDirEntryPosition (partition, &entryEnd, false) == false) { - end = true; - } - } - return false; -} - -bool _FAT_directory_entryFromPosition (PARTITION* partition, DIR_ENTRY* entry) { - DIR_ENTRY_POSITION entryStart = entry->dataStart; - DIR_ENTRY_POSITION entryEnd = entry->dataEnd; - bool entryStillValid; - bool finished; - ucs2_t lfn[MAX_LFN_LENGTH]; - int i; - int lfnPos; - uint8_t entryData[DIR_ENTRY_DATA_SIZE]; - - memset (entry->filename, '\0', MAX_FILENAME_LENGTH); - - // Create an empty directory entry to overwrite the old ones with - for ( entryStillValid = true, finished = false; - entryStillValid && !finished; - entryStillValid = _FAT_directory_incrementDirEntryPosition (partition, &entryStart, false)) - { - _FAT_cache_readPartialSector (partition->cache, entryData, - _FAT_fat_clusterToSector(partition, entryStart.cluster) + entryStart.sector, - entryStart.offset * DIR_ENTRY_DATA_SIZE, DIR_ENTRY_DATA_SIZE); - - if ((entryStart.cluster == entryEnd.cluster) - && (entryStart.sector == entryEnd.sector) - && (entryStart.offset == entryEnd.offset)) { - // Copy the entry data and stop, since this is the last section of the directory entry - memcpy (entry->entryData, entryData, DIR_ENTRY_DATA_SIZE); - finished = true; - } else { - // Copy the long file name data - lfnPos = ((entryData[LFN_offset_ordinal] & ~LFN_END) - 1) * 13; - if (lfnPos > LAST_LFN_POS) { - lfnPos = LAST_LFN_POS_CORRECTION; - } - for (i = 0; i < 13; i++) { - lfn[lfnPos + i] = entryData[LFN_offset_table[i]] | (entryData[LFN_offset_table[i]+1] << 8); - } - } - } - - if (!entryStillValid) { - return false; - } - - if ((entryStart.cluster == entryEnd.cluster) - && (entryStart.sector == entryEnd.sector) - && (entryStart.offset == entryEnd.offset)) { - // Since the entry doesn't have a long file name, extract the short filename - if (!_FAT_directory_entryGetAlias (entry->entryData, entry->filename)) { - return false; - } - } else { - // Encode the long file name into a multibyte string - if (_FAT_directory_ucs2tombs (entry->filename, lfn, MAX_FILENAME_LENGTH) == (size_t)-1) { - return false; - } - } - - return true; -} - - - -bool _FAT_directory_entryFromPath (PARTITION* partition, DIR_ENTRY* entry, const char* path, const char* pathEnd) { - size_t dirnameLength; - const char* pathPosition; - const char* nextPathPosition; - uint32_t dirCluster; - bool foundFile; - char alias[MAX_ALIAS_LENGTH]; - bool found, notFound; - - pathPosition = path; - - found = false; - notFound = false; - - if (pathEnd == NULL) { - // Set pathEnd to the end of the path string - pathEnd = strchr (path, '\0'); - } - - if (pathPosition[0] == DIR_SEPARATOR) { - // Start at root directory - dirCluster = partition->rootDirCluster; - // Consume separator(s) - while (pathPosition[0] == DIR_SEPARATOR) { - pathPosition++; - } - // If the path is only specifying a directory in the form of "/" return it - if (pathPosition >= pathEnd) { - _FAT_directory_getRootEntry (partition, entry); - found = true; - } - } else { - // Start in current working directory - dirCluster = partition->cwdCluster; - } - - while (!found && !notFound) { - // Get the name of the next required subdirectory within the path - nextPathPosition = strchr (pathPosition, DIR_SEPARATOR); - if (nextPathPosition != NULL) { - dirnameLength = nextPathPosition - pathPosition; - } else { - dirnameLength = strlen(pathPosition); - } - - if (dirnameLength > MAX_FILENAME_LENGTH) { - // The path is too long to bother with - return false; - } - - // Check for "." or ".." when the dirCluster is root cluster - // These entries do not exist, so we must fake it - if ((dirCluster == partition->rootDirCluster) - && ((strncmp(".", pathPosition, dirnameLength) == 0) - || (strncmp("..", pathPosition, dirnameLength) == 0))) { - foundFile = true; - _FAT_directory_getRootEntry(partition, entry); - } else { - // Look for the directory within the path - foundFile = _FAT_directory_getFirstEntry (partition, entry, dirCluster); - - while (foundFile && !found && !notFound) { // It hasn't already found the file - // Check if the filename matches - if ((dirnameLength == strnlen(entry->filename, MAX_FILENAME_LENGTH)) - && (_FAT_directory_mbsncasecmp(pathPosition, entry->filename, dirnameLength) == 0)) { - found = true; - } - - // Check if the alias matches - _FAT_directory_entryGetAlias (entry->entryData, alias); - if ((dirnameLength == strnlen(alias, MAX_ALIAS_LENGTH)) - && (strncasecmp(pathPosition, alias, dirnameLength) == 0)) { - found = true; - } - - if (found && !(entry->entryData[DIR_ENTRY_attributes] & ATTRIB_DIR) && (nextPathPosition != NULL)) { - // Make sure that we aren't trying to follow a file instead of a directory in the path - found = false; - } - - if (!found) { - foundFile = _FAT_directory_getNextEntry (partition, entry); - } - } - } - - if (!foundFile) { - // Check that the search didn't get to the end of the directory - notFound = true; - found = false; - } else if ((nextPathPosition == NULL) || (nextPathPosition >= pathEnd)) { - // Check that we reached the end of the path - found = true; - } else if (entry->entryData[DIR_ENTRY_attributes] & ATTRIB_DIR) { - dirCluster = _FAT_directory_entryGetCluster (partition, entry->entryData); - if (dirCluster == CLUSTER_ROOT) - dirCluster = partition->rootDirCluster; - pathPosition = nextPathPosition; - // Consume separator(s) - while (pathPosition[0] == DIR_SEPARATOR) { - pathPosition++; - } - // The requested directory was found - if (pathPosition >= pathEnd) { - found = true; - } else { - found = false; - } - } - } - - if (found && !notFound) { - if (partition->filesysType == FS_FAT32 && (entry->entryData[DIR_ENTRY_attributes] & ATTRIB_DIR) && - _FAT_directory_entryGetCluster (partition, entry->entryData) == CLUSTER_ROOT) - { - // On FAT32 it should specify an actual cluster for the root entry, - // not cluster 0 as on FAT16 - _FAT_directory_getRootEntry (partition, entry); - } - return true; - } else { - return false; - } -} - -bool _FAT_directory_removeEntry (PARTITION* partition, DIR_ENTRY* entry) { - DIR_ENTRY_POSITION entryStart = entry->dataStart; - DIR_ENTRY_POSITION entryEnd = entry->dataEnd; - bool entryStillValid; - bool finished; - uint8_t entryData[DIR_ENTRY_DATA_SIZE]; - - // Create an empty directory entry to overwrite the old ones with - for ( entryStillValid = true, finished = false; - entryStillValid && !finished; - entryStillValid = _FAT_directory_incrementDirEntryPosition (partition, &entryStart, false)) - { - _FAT_cache_readPartialSector (partition->cache, entryData, _FAT_fat_clusterToSector(partition, entryStart.cluster) + entryStart.sector, entryStart.offset * DIR_ENTRY_DATA_SIZE, DIR_ENTRY_DATA_SIZE); - entryData[0] = DIR_ENTRY_FREE; - _FAT_cache_writePartialSector (partition->cache, entryData, _FAT_fat_clusterToSector(partition, entryStart.cluster) + entryStart.sector, entryStart.offset * DIR_ENTRY_DATA_SIZE, DIR_ENTRY_DATA_SIZE); - if ((entryStart.cluster == entryEnd.cluster) && (entryStart.sector == entryEnd.sector) && (entryStart.offset == entryEnd.offset)) { - finished = true; - } - } - - if (!entryStillValid) { - return false; - } - - return true; -} - -static bool _FAT_directory_findEntryGap (PARTITION* partition, DIR_ENTRY* entry, uint32_t dirCluster, size_t size) { - DIR_ENTRY_POSITION gapStart; - DIR_ENTRY_POSITION gapEnd; - uint8_t entryData[DIR_ENTRY_DATA_SIZE]; - size_t dirEntryRemain; - bool endOfDirectory, entryStillValid; - - // Scan Dir for free entry - gapEnd.offset = 0; - gapEnd.sector = 0; - gapEnd.cluster = dirCluster; - - gapStart = gapEnd; - - entryStillValid = true; - dirEntryRemain = size; - endOfDirectory = false; - - while (entryStillValid && !endOfDirectory && (dirEntryRemain > 0)) { - _FAT_cache_readPartialSector (partition->cache, entryData, - _FAT_fat_clusterToSector(partition, gapEnd.cluster) + gapEnd.sector, - gapEnd.offset * DIR_ENTRY_DATA_SIZE, DIR_ENTRY_DATA_SIZE); - if (entryData[0] == DIR_ENTRY_LAST) { - gapStart = gapEnd; - -- dirEntryRemain; - endOfDirectory = true; - } else if (entryData[0] == DIR_ENTRY_FREE) { - if (dirEntryRemain == size) { - gapStart = gapEnd; - } - -- dirEntryRemain; - } else { - dirEntryRemain = size; - } - - if (!endOfDirectory && (dirEntryRemain > 0)) { - entryStillValid = _FAT_directory_incrementDirEntryPosition (partition, &gapEnd, true); - } - } - - // Make sure the scanning didn't fail - if (!entryStillValid) { - return false; - } - - // Save the start entry, since we know it is valid - entry->dataStart = gapStart; - - if (endOfDirectory) { - memset (entryData, DIR_ENTRY_LAST, DIR_ENTRY_DATA_SIZE); - dirEntryRemain += 1; // Increase by one to take account of End Of Directory Marker - while ((dirEntryRemain > 0) && entryStillValid) { - // Get the gapEnd before incrementing it, so the second to last one is saved - entry->dataEnd = gapEnd; - // Increment gapEnd, moving onto the next entry - entryStillValid = _FAT_directory_incrementDirEntryPosition (partition, &gapEnd, true); - -- dirEntryRemain; - // Fill the entry with blanks - _FAT_cache_writePartialSector (partition->cache, entryData, - _FAT_fat_clusterToSector(partition, gapEnd.cluster) + gapEnd.sector, - gapEnd.offset * DIR_ENTRY_DATA_SIZE, DIR_ENTRY_DATA_SIZE); - } - if (!entryStillValid) { - return false; - } - } else { - entry->dataEnd = gapEnd; - } - - return true; -} - -static bool _FAT_directory_entryExists (PARTITION* partition, const char* name, uint32_t dirCluster) { - DIR_ENTRY tempEntry; - bool foundFile; - char alias[MAX_ALIAS_LENGTH]; - size_t dirnameLength; - - dirnameLength = strnlen(name, MAX_FILENAME_LENGTH); - - if (dirnameLength >= MAX_FILENAME_LENGTH) { - return false; - } - - // Make sure the entry doesn't already exist - foundFile = _FAT_directory_getFirstEntry (partition, &tempEntry, dirCluster); - - while (foundFile) { // It hasn't already found the file - // Check if the filename matches - if ((dirnameLength == strnlen(tempEntry.filename, MAX_FILENAME_LENGTH)) - && (_FAT_directory_mbsncasecmp(name, tempEntry.filename, dirnameLength) == 0)) { - return true; - } - - // Check if the alias matches - _FAT_directory_entryGetAlias (tempEntry.entryData, alias); - if ((strncasecmp(name, alias, MAX_ALIAS_LENGTH) == 0)) { - return true; - } - foundFile = _FAT_directory_getNextEntry (partition, &tempEntry); - } - return false; -} - -/* -Creates an alias for a long file name. If the alias is not an exact match for the -filename, it returns the number of characters in the alias. If the two names match, -it returns 0. If there was an error, it returns -1. -*/ -static int _FAT_directory_createAlias (char* alias, const char* lfn) { - bool lossyConversion = false; // Set when the alias had to be modified to be valid - int lfnPos = 0; - int aliasPos = 0; - wchar_t lfnChar; - int oemChar; - mbstate_t ps = {0}; - int bytesUsed = 0; - const char* lfnExt; - int aliasExtLen; - - // Strip leading periods - while (lfn[lfnPos] == '.') { - lfnPos ++; - lossyConversion = true; - } - - // Primary portion of alias - while (aliasPos < 8 && lfn[lfnPos] != '.' && lfn[lfnPos] != '\0') { - bytesUsed = mbrtowc(&lfnChar, lfn + lfnPos, MAX_FILENAME_LENGTH - lfnPos, &ps); - if (bytesUsed < 0) { - return -1; - } - oemChar = wctob(towupper((wint_t)lfnChar)); - if (wctob((wint_t)lfnChar) != oemChar) { - // Case of letter was changed - lossyConversion = true; - } - if (oemChar == ' ') { - // Skip spaces in filename - lossyConversion = true; - lfnPos += bytesUsed; - continue; - } - if (oemChar == EOF) { - oemChar = '_'; // Replace unconvertable characters with underscores - lossyConversion = true; - } - if (strchr (ILLEGAL_ALIAS_CHARACTERS, oemChar) != NULL) { - // Invalid Alias character - oemChar = '_'; // Replace illegal characters with underscores - lossyConversion = true; - } - - alias[aliasPos] = (char)oemChar; - aliasPos++; - lfnPos += bytesUsed; - } - - if (lfn[lfnPos] != '.' && lfn[lfnPos] != '\0') { - // Name was more than 8 characters long - lossyConversion = true; - } - - // Alias extension - lfnExt = strrchr (lfn, '.'); - if (lfnExt != NULL && lfnExt != strchr (lfn, '.')) { - // More than one period in name - lossyConversion = true; - } - if (lfnExt != NULL && lfnExt[1] != '\0') { - lfnExt++; - alias[aliasPos] = '.'; - aliasPos++; - memset (&ps, 0, sizeof(ps)); - for (aliasExtLen = 0; aliasExtLen < MAX_ALIAS_EXT_LENGTH && *lfnExt != '\0'; aliasExtLen++) { - bytesUsed = mbrtowc(&lfnChar, lfnExt, MAX_FILENAME_LENGTH - lfnPos, &ps); - if (bytesUsed < 0) { - return -1; - } - oemChar = wctob(towupper((wint_t)lfnChar)); - if (wctob((wint_t)lfnChar) != oemChar) { - // Case of letter was changed - lossyConversion = true; - } - if (oemChar == ' ') { - // Skip spaces in alias - lossyConversion = true; - lfnExt += bytesUsed; - continue; - } - if (oemChar == EOF) { - oemChar = '_'; // Replace unconvertable characters with underscores - lossyConversion = true; - } - if (strchr (ILLEGAL_ALIAS_CHARACTERS, oemChar) != NULL) { - // Invalid Alias character - oemChar = '_'; // Replace illegal characters with underscores - lossyConversion = true; - } - - alias[aliasPos] = (char)oemChar; - aliasPos++; - lfnExt += bytesUsed; - } - if (*lfnExt != '\0') { - // Extension was more than 3 characters long - lossyConversion = true; - } - } - - alias[aliasPos] = '\0'; - if (lossyConversion) { - return aliasPos; - } else { - return 0; - } -} - -bool _FAT_directory_addEntry (PARTITION* partition, DIR_ENTRY* entry, uint32_t dirCluster) { - size_t entrySize; - uint8_t lfnEntry[DIR_ENTRY_DATA_SIZE]; - int i,j; // Must be signed for use when decrementing in for loop - char *tmpCharPtr; - DIR_ENTRY_POSITION curEntryPos; - bool entryStillValid; - uint8_t aliasCheckSum = 0; - char alias [MAX_ALIAS_LENGTH]; - int aliasLen; - int lfnLen; - - // Make sure the filename is not 0 length - if (strnlen (entry->filename, MAX_FILENAME_LENGTH) < 1) { - return false; - } - - // Make sure the filename is at least a valid LFN - lfnLen = _FAT_directory_lfnLength (entry->filename); - if (lfnLen < 0) { - return false; - } - - // Remove trailing spaces - for (i = strlen (entry->filename) - 1; (i > 0) && (entry->filename[i] == ' '); --i) { - entry->filename[i] = '\0'; - } - // Remove leading spaces - for (i = 0; (i < (int)strlen (entry->filename)) && (entry->filename[i] == ' '); ++i) ; - if (i > 0) { - memmove (entry->filename, entry->filename + i, strlen (entry->filename + i)); - } - - // Remove junk in filename - i = strlen (entry->filename); - memset (entry->filename + i, '\0', MAX_FILENAME_LENGTH - i); - - // Make sure the entry doesn't already exist - if (_FAT_directory_entryExists (partition, entry->filename, dirCluster)) { - return false; - } - - // Clear out alias, so we can generate a new one - memset (entry->entryData, ' ', 11); - - if ( strncmp(entry->filename, ".", MAX_FILENAME_LENGTH) == 0) { - // "." entry - entry->entryData[0] = '.'; - entrySize = 1; - } else if ( strncmp(entry->filename, "..", MAX_FILENAME_LENGTH) == 0) { - // ".." entry - entry->entryData[0] = '.'; - entry->entryData[1] = '.'; - entrySize = 1; - } else { - // Normal file name - aliasLen = _FAT_directory_createAlias (alias, entry->filename); - if (aliasLen < 0) { - return false; - } else if (aliasLen == 0) { - // It's a normal short filename - entrySize = 1; - } else { - // It's a long filename with an alias - entrySize = ((lfnLen + LFN_ENTRY_LENGTH - 1) / LFN_ENTRY_LENGTH) + 1; - - // Generate full alias for all cases except when the alias is simply an upper case version of the LFN - // and there isn't already a file with that name - if (strncasecmp (alias, entry->filename, MAX_ALIAS_LENGTH) != 0 || - _FAT_directory_entryExists (partition, alias, dirCluster)) - { - // expand primary part to 8 characters long by padding the end with underscores - i = MAX_ALIAS_PRI_LENGTH - 1; - // Move extension to last 3 characters - while (alias[i] != '.' && i > 0) i--; - if (i > 0) { - j = MAX_ALIAS_LENGTH - MAX_ALIAS_EXT_LENGTH - 2; // 1 char for '.', one for NUL, 3 for extension - memmove (alias + j, alias + i, strlen(alias) - i); - // Pad primary component - memset (alias + i, '_', j - i); - alias[MAX_ALIAS_LENGTH-1]=0; - } - - // Generate numeric tail - for (i = 1; i <= MAX_NUMERIC_TAIL; i++) { - j = i; - tmpCharPtr = alias + MAX_ALIAS_PRI_LENGTH - 1; - while (j > 0) { - *tmpCharPtr = '0' + (j % 10); // ASCII numeric value - tmpCharPtr--; - j /= 10; - } - *tmpCharPtr = '~'; - if (!_FAT_directory_entryExists (partition, alias, dirCluster)) { - break; - } - } - if (i > MAX_NUMERIC_TAIL) { - // Couldn't get a valid alias - return false; - } - } - } - - // Copy alias or short file name into directory entry data - for (i = 0, j = 0; (j < 8) && (alias[i] != '.') && (alias[i] != '\0'); i++, j++) { - entry->entryData[j] = alias[i]; - } - while (j < 8) { - entry->entryData[j] = ' '; - ++ j; - } - if (alias[i] == '.') { - // Copy extension - ++ i; - while ((alias[i] != '\0') && (j < 11)) { - entry->entryData[j] = alias[i]; - ++ i; - ++ j; - } - } - while (j < 11) { - entry->entryData[j] = ' '; - ++ j; - } - - // Generate alias checksum - for (i=0; i < ALIAS_ENTRY_LENGTH; i++) { - // NOTE: The operation is an unsigned char rotate right - aliasCheckSum = ((aliasCheckSum & 1) ? 0x80 : 0) + (aliasCheckSum >> 1) + entry->entryData[i]; - } - } - - // Find or create space for the entry - if (_FAT_directory_findEntryGap (partition, entry, dirCluster, entrySize) == false) { - return false; - } - - // Write out directory entry - curEntryPos = entry->dataStart; - - { - // lfn is only pushed onto the stack here, reducing overall stack usage - ucs2_t lfn[MAX_LFN_LENGTH] = {0}; - _FAT_directory_mbstoucs2 (lfn, entry->filename, MAX_LFN_LENGTH); - - for (entryStillValid = true, i = entrySize; entryStillValid && i > 0; - entryStillValid = _FAT_directory_incrementDirEntryPosition (partition, &curEntryPos, false), -- i ) - { - if (i > 1) { - // Long filename entry - lfnEntry[LFN_offset_ordinal] = (i - 1) | ((size_t)i == entrySize ? LFN_END : 0); - for (j = 0; j < 13; j++) { - if (lfn [(i - 2) * 13 + j] == '\0') { - if ((j > 1) && (lfn [(i - 2) * 13 + (j-1)] == '\0')) { - u16_to_u8array (lfnEntry, LFN_offset_table[j], 0xffff); // Padding - } else { - u16_to_u8array (lfnEntry, LFN_offset_table[j], 0x0000); // Terminating null character - } - } else { - u16_to_u8array (lfnEntry, LFN_offset_table[j], lfn [(i - 2) * 13 + j]); - } - } - - lfnEntry[LFN_offset_checkSum] = aliasCheckSum; - lfnEntry[LFN_offset_flag] = ATTRIB_LFN; - lfnEntry[LFN_offset_reserved1] = 0; - u16_to_u8array (lfnEntry, LFN_offset_reserved2, 0); - _FAT_cache_writePartialSector (partition->cache, lfnEntry, _FAT_fat_clusterToSector(partition, curEntryPos.cluster) + curEntryPos.sector, curEntryPos.offset * DIR_ENTRY_DATA_SIZE, DIR_ENTRY_DATA_SIZE); - } else { - // Alias & file data - _FAT_cache_writePartialSector (partition->cache, entry->entryData, _FAT_fat_clusterToSector(partition, curEntryPos.cluster) + curEntryPos.sector, curEntryPos.offset * DIR_ENTRY_DATA_SIZE, DIR_ENTRY_DATA_SIZE); - } - } - } - - return true; -} - -bool _FAT_directory_chdir (PARTITION* partition, const char* path) { - DIR_ENTRY entry; - - if (!_FAT_directory_entryFromPath (partition, &entry, path, NULL)) { - return false; - } - - if (!(entry.entryData[DIR_ENTRY_attributes] & ATTRIB_DIR)) { - return false; - } - - partition->cwdCluster = _FAT_directory_entryGetCluster (partition, entry.entryData); - - return true; -} - -void _FAT_directory_entryStat (PARTITION* partition, DIR_ENTRY* entry, struct stat *st) { - // Fill in the stat struct - // Some of the values are faked for the sake of compatibility - st->st_dev = _FAT_disc_hostType(partition->disc); // The device is the 32bit ioType value - st->st_ino = (ino_t)(_FAT_directory_entryGetCluster(partition, entry->entryData)); // The file serial number is the start cluster - st->st_mode = (_FAT_directory_isDirectory(entry) ? S_IFDIR : S_IFREG) | - (S_IRUSR | S_IRGRP | S_IROTH) | - (_FAT_directory_isWritable (entry) ? (S_IWUSR | S_IWGRP | S_IWOTH) : 0); // Mode bits based on dirEntry ATTRIB byte - st->st_nlink = 1; // Always one hard link on a FAT file - st->st_uid = 1; // Faked for FAT - st->st_gid = 2; // Faked for FAT - st->st_rdev = st->st_dev; - st->st_size = u8array_to_u32 (entry->entryData, DIR_ENTRY_fileSize); // File size - st->st_atime = _FAT_filetime_to_time_t ( - 0, - u8array_to_u16 (entry->entryData, DIR_ENTRY_aDate) - ); - st->st_spare1 = 0; - st->st_mtime = _FAT_filetime_to_time_t ( - u8array_to_u16 (entry->entryData, DIR_ENTRY_mTime), - u8array_to_u16 (entry->entryData, DIR_ENTRY_mDate) - ); - st->st_spare2 = 0; - st->st_ctime = _FAT_filetime_to_time_t ( - u8array_to_u16 (entry->entryData, DIR_ENTRY_cTime), - u8array_to_u16 (entry->entryData, DIR_ENTRY_cDate) - ); - st->st_spare3 = 0; - st->st_blksize = partition->bytesPerSector; // Prefered file I/O block size - st->st_blocks = (st->st_size + partition->bytesPerSector - 1) / partition->bytesPerSector; // File size in blocks - st->st_spare4[0] = 0; - st->st_spare4[1] = 0; -} diff --git a/cube/libfat-frag/src/source/directory.h b/cube/libfat-frag/src/source/directory.h deleted file mode 100644 index ac66c781..00000000 --- a/cube/libfat-frag/src/source/directory.h +++ /dev/null @@ -1,181 +0,0 @@ -/* - directory.h - Reading, writing and manipulation of the directory structure on - a FAT partition - - Copyright (c) 2006 Michael "Chishm" Chisholm - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef _DIRECTORY_H -#define _DIRECTORY_H - -#include - -#include "common.h" -#include "partition.h" - -#define DIR_ENTRY_DATA_SIZE 0x20 -#define MAX_LFN_LENGTH 256 -#define MAX_FILENAME_LENGTH 768 // 256 UCS-2 characters encoded into UTF-8 can use up to 768 UTF-8 chars -#define MAX_ALIAS_LENGTH 13 -#define LFN_ENTRY_LENGTH 13 -#define ALIAS_ENTRY_LENGTH 11 -#define MAX_ALIAS_EXT_LENGTH 3 -#define MAX_ALIAS_PRI_LENGTH 8 -#define MAX_NUMERIC_TAIL 999999 -#define FAT16_ROOT_DIR_CLUSTER 0 - -#define DIR_SEPARATOR '/' - -// File attributes -#define ATTRIB_ARCH 0x20 // Archive -#define ATTRIB_DIR 0x10 // Directory -#define ATTRIB_LFN 0x0F // Long file name -#define ATTRIB_VOL 0x08 // Volume -#define ATTRIB_SYS 0x04 // System -#define ATTRIB_HID 0x02 // Hidden -#define ATTRIB_RO 0x01 // Read only - -#define CASE_LOWER_EXT 0x10 // WinNT lowercase extension -#define CASE_LOWER_BASE 0x08 // WinNT lowercase basename - -typedef enum {FT_DIRECTORY, FT_FILE} FILE_TYPE; - -typedef struct { - uint32_t cluster; - sec_t sector; - int32_t offset; -} DIR_ENTRY_POSITION; - -typedef struct { - uint8_t entryData[DIR_ENTRY_DATA_SIZE]; - DIR_ENTRY_POSITION dataStart; // Points to the start of the LFN entries of a file, or the alias for no LFN - DIR_ENTRY_POSITION dataEnd; // Always points to the file/directory's alias entry - char filename[MAX_FILENAME_LENGTH]; -} DIR_ENTRY; - -// Directory entry offsets -enum DIR_ENTRY_offset { - DIR_ENTRY_name = 0x00, - DIR_ENTRY_extension = 0x08, - DIR_ENTRY_attributes = 0x0B, - DIR_ENTRY_caseInfo = 0x0C, - DIR_ENTRY_cTime_ms = 0x0D, - DIR_ENTRY_cTime = 0x0E, - DIR_ENTRY_cDate = 0x10, - DIR_ENTRY_aDate = 0x12, - DIR_ENTRY_clusterHigh = 0x14, - DIR_ENTRY_mTime = 0x16, - DIR_ENTRY_mDate = 0x18, - DIR_ENTRY_cluster = 0x1A, - DIR_ENTRY_fileSize = 0x1C -}; - -/* -Returns true if the file specified by entry is a directory -*/ -static inline bool _FAT_directory_isDirectory (DIR_ENTRY* entry) { - return ((entry->entryData[DIR_ENTRY_attributes] & ATTRIB_DIR) != 0); -} - -static inline bool _FAT_directory_isWritable (DIR_ENTRY* entry) { - return ((entry->entryData[DIR_ENTRY_attributes] & ATTRIB_RO) == 0); -} - -static inline bool _FAT_directory_isDot (DIR_ENTRY* entry) { - return ((entry->filename[0] == '.') && ((entry->filename[1] == '\0') || - ((entry->filename[1] == '.') && entry->filename[2] == '\0'))); -} - -/* -Reads the first directory entry from the directory starting at dirCluster -Places result in entry -entry will be destroyed even if no directory entry is found -Returns true on success, false on failure -*/ -bool _FAT_directory_getFirstEntry (PARTITION* partition, DIR_ENTRY* entry, uint32_t dirCluster); - -/* -Reads the next directory entry after the one already pointed to by entry -Places result in entry -entry will be destroyed even if no directory entry is found -Returns true on success, false on failure -*/ -bool _FAT_directory_getNextEntry (PARTITION* partition, DIR_ENTRY* entry); - -/* -Gets the directory entry corrsponding to the supplied path -entry will be destroyed even if no directory entry is found -pathEnd specifies the end of the path string, for cutting strings short if needed - specify NULL to use the full length of path - pathEnd is only a suggestion, and the path string will be searched up until the next PATH_SEPARATOR - after pathEND. -Returns true on success, false on failure -*/ -bool _FAT_directory_entryFromPath (PARTITION* partition, DIR_ENTRY* entry, const char* path, const char* pathEnd); - -/* -Changes the current directory to the one specified by path -Returns true on success, false on failure -*/ -bool _FAT_directory_chdir (PARTITION* partition, const char* path); - -/* -Removes the directory entry specified by entry -Assumes that entry is valid -Returns true on success, false on failure -*/ -bool _FAT_directory_removeEntry (PARTITION* partition, DIR_ENTRY* entry); - -/* -Add a directory entry to the directory specified by dirCluster -The fileData, dataStart and dataEnd elements of the DIR_ENTRY struct are -updated with the new directory entry position and alias. -Returns true on success, false on failure -*/ -bool _FAT_directory_addEntry (PARTITION* partition, DIR_ENTRY* entry, uint32_t dirCluster); - -/* -Get the start cluster of a file from it's entry data -*/ -uint32_t _FAT_directory_entryGetCluster (PARTITION* partition, const uint8_t* entryData); - -/* -Fill in the file name and entry data of DIR_ENTRY* entry. -Assumes that the entry's dataStart and dataEnd are correct -Returns true on success, false on failure -*/ -bool _FAT_directory_entryFromPosition (PARTITION* partition, DIR_ENTRY* entry); - -/* -Fill in a stat struct based on a file entry -*/ -void _FAT_directory_entryStat (PARTITION* partition, DIR_ENTRY* entry, struct stat *st); - -/* -Get volume label -*/ -bool _FAT_directory_getVolumeLabel (PARTITION* partition, char *label); - -#endif // _DIRECTORY_H diff --git a/cube/libfat-frag/src/source/disc.c b/cube/libfat-frag/src/source/disc.c deleted file mode 100644 index 5f626b6b..00000000 --- a/cube/libfat-frag/src/source/disc.c +++ /dev/null @@ -1,111 +0,0 @@ -/* - disc.c - Interface to the low level disc functions. Used by the higher level - file system code. - - Copyright (c) 2008 Michael "Chishm" Chisholm - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include "disc.h" - -/* -The list of interfaces consists of a series of name/interface pairs. -The interface is returned via a simple function. This allows for -platforms where the interface has to be "assembled" before it can -be used, like DLDI on the NDS. For cases where a simple struct -is available, wrapper functions are used. -The list is terminated by a NULL/NULL entry. -*/ - -/* ====================== Wii ====================== */ -#if defined (__wii__) -#include -#include -#include - -static const DISC_INTERFACE* get_io_wiisd (void) { - return &__io_wiisd; -} -static const DISC_INTERFACE* get_io_usbstorage (void) { - return &__io_usbstorage; -} - -static const DISC_INTERFACE* get_io_gcsda (void) { - return &__io_gcsda; -} - -static const DISC_INTERFACE* get_io_gcsdb (void) { - return &__io_gcsdb; -} - -const INTERFACE_ID _FAT_disc_interfaces[] = { - {"sd", get_io_wiisd}, - {"usb", get_io_usbstorage}, - {"carda", get_io_gcsda}, - {"cardb", get_io_gcsdb}, - {NULL, NULL} -}; - -/* ==================== Gamecube ==================== */ -#elif defined (__gamecube__) -#include - -static const DISC_INTERFACE* get_io_gcsda (void) { - return &__io_gcsda; -} -static const DISC_INTERFACE* get_io_gcsdb (void) { - return &__io_gcsdb; -} - -const INTERFACE_ID _FAT_disc_interfaces[] = { - {"carda", get_io_gcsda}, - {"cardb", get_io_gcsdb}, - {NULL, NULL} -}; - -/* ====================== NDS ====================== */ -#elif defined (NDS) -#include - -static const DISC_INTERFACE* get_io_dsisd (void) { - return &__io_dsisd; -} - -const INTERFACE_ID _FAT_disc_interfaces[] = { - {"sd", get_io_dsisd}, - {"fat", dldiGetInternal}, - {NULL, NULL} -}; - -/* ====================== GBA ====================== */ -#elif defined (GBA) -#include - -const INTERFACE_ID _FAT_disc_interfaces[] = { - {"fat", discGetInterface}, - {NULL, NULL} -}; - -#endif - diff --git a/cube/libfat-frag/src/source/disc.h b/cube/libfat-frag/src/source/disc.h deleted file mode 100644 index 5c955f90..00000000 --- a/cube/libfat-frag/src/source/disc.h +++ /dev/null @@ -1,110 +0,0 @@ -/* - disc.h - Interface to the low level disc functions. Used by the higher level - file system code. - - Copyright (c) 2006 Michael "Chishm" Chisholm - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ -#ifndef _DISC_H -#define _DISC_H - -#include "common.h" - -/* -A list of all default devices to try at startup, -terminated by a {NULL,NULL} entry. -*/ -typedef struct { - const char* name; - const DISC_INTERFACE* (*getInterface)(void); -} INTERFACE_ID; -extern const INTERFACE_ID _FAT_disc_interfaces[]; - -/* -Check if a disc is inserted -Return true if a disc is inserted and ready, false otherwise -*/ -static inline bool _FAT_disc_isInserted (const DISC_INTERFACE* disc) { - return disc->isInserted(); -} - -/* -Read numSectors sectors from a disc, starting at sector. -numSectors is between 1 and LIMIT_SECTORS if LIMIT_SECTORS is defined, -else it is at least 1 -sector is 0 or greater -buffer is a pointer to the memory to fill -*/ -static inline bool _FAT_disc_readSectors (const DISC_INTERFACE* disc, sec_t sector, sec_t numSectors, void* buffer) { - return disc->readSectors (sector, numSectors, buffer); -} - -/* -Write numSectors sectors to a disc, starting at sector. -numSectors is between 1 and LIMIT_SECTORS if LIMIT_SECTORS is defined, -else it is at least 1 -sector is 0 or greater -buffer is a pointer to the memory to read from -*/ -static inline bool _FAT_disc_writeSectors (const DISC_INTERFACE* disc, sec_t sector, sec_t numSectors, const void* buffer) { - return disc->writeSectors (sector, numSectors, buffer); -} - -/* -Reset the card back to a ready state -*/ -static inline bool _FAT_disc_clearStatus (const DISC_INTERFACE* disc) { - return disc->clearStatus(); -} - -/* -Initialise the disc to a state ready for data reading or writing -*/ -static inline bool _FAT_disc_startup (const DISC_INTERFACE* disc) { - return disc->startup(); -} - -/* -Put the disc in a state ready for power down. -Complete any pending writes and disable the disc if necessary -*/ -static inline bool _FAT_disc_shutdown (const DISC_INTERFACE* disc) { - return disc->shutdown(); -} - -/* -Return a 32 bit value unique to each type of interface -*/ -static inline uint32_t _FAT_disc_hostType (const DISC_INTERFACE* disc) { - return disc->ioType; -} - -/* -Return a 32 bit value that specifies the capabilities of the disc -*/ -static inline uint32_t _FAT_disc_features (const DISC_INTERFACE* disc) { - return disc->features; -} - -#endif // _DISC_H diff --git a/cube/libfat-frag/src/source/fatdir.c b/cube/libfat-frag/src/source/fatdir.c deleted file mode 100644 index fe0e781e..00000000 --- a/cube/libfat-frag/src/source/fatdir.c +++ /dev/null @@ -1,619 +0,0 @@ -/* - fatdir.c - - Functions used by the newlib disc stubs to interface with - this library - - Copyright (c) 2006 Michael "Chishm" Chisholm - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include -#include -#include -#include -#include - -#include "fatdir.h" - -#include "cache.h" -#include "file_allocation_table.h" -#include "partition.h" -#include "directory.h" -#include "bit_ops.h" -#include "filetime.h" -#include "lock.h" - - -int _FAT_stat_r (struct _reent *r, const char *path, struct stat *st) { - PARTITION* partition = NULL; - DIR_ENTRY dirEntry; - - // Get the partition this file is on - partition = _FAT_partition_getPartitionFromPath (path); - if (partition == NULL) { - r->_errno = ENODEV; - return -1; - } - - // Move the path pointer to the start of the actual path - if (strchr (path, ':') != NULL) { - path = strchr (path, ':') + 1; - } - if (strchr (path, ':') != NULL) { - r->_errno = EINVAL; - return -1; - } - - _FAT_lock(&partition->lock); - - // Search for the file on the disc - if (!_FAT_directory_entryFromPath (partition, &dirEntry, path, NULL)) { - _FAT_unlock(&partition->lock); - r->_errno = ENOENT; - return -1; - } - - // Fill in the stat struct - _FAT_directory_entryStat (partition, &dirEntry, st); - - _FAT_unlock(&partition->lock); - return 0; -} - -int _FAT_link_r (struct _reent *r, const char *existing, const char *newLink) { - r->_errno = ENOTSUP; - return -1; -} - -int _FAT_unlink_r (struct _reent *r, const char *path) { - PARTITION* partition = NULL; - DIR_ENTRY dirEntry; - DIR_ENTRY dirContents; - uint32_t cluster; - bool nextEntry; - bool errorOccured = false; - - // Get the partition this directory is on - partition = _FAT_partition_getPartitionFromPath (path); - if (partition == NULL) { - r->_errno = ENODEV; - return -1; - } - - // Make sure we aren't trying to write to a read-only disc - if (partition->readOnly) { - r->_errno = EROFS; - return -1; - } - - // Move the path pointer to the start of the actual path - if (strchr (path, ':') != NULL) { - path = strchr (path, ':') + 1; - } - if (strchr (path, ':') != NULL) { - r->_errno = EINVAL; - return -1; - } - - _FAT_lock(&partition->lock); - - // Search for the file on the disc - if (!_FAT_directory_entryFromPath (partition, &dirEntry, path, NULL)) { - _FAT_unlock(&partition->lock); - r->_errno = ENOENT; - return -1; - } - - cluster = _FAT_directory_entryGetCluster (partition, dirEntry.entryData); - - - // If this is a directory, make sure it is empty - if (_FAT_directory_isDirectory (&dirEntry)) { - nextEntry = _FAT_directory_getFirstEntry (partition, &dirContents, cluster); - - while (nextEntry) { - if (!_FAT_directory_isDot (&dirContents)) { - // The directory had something in it that isn't a reference to itself or it's parent - _FAT_unlock(&partition->lock); - r->_errno = EPERM; - return -1; - } - nextEntry = _FAT_directory_getNextEntry (partition, &dirContents); - } - } - - if (_FAT_fat_isValidCluster(partition, cluster)) { - // Remove the cluster chain for this file - if (!_FAT_fat_clearLinks (partition, cluster)) { - r->_errno = EIO; - errorOccured = true; - } - } - - // Remove the directory entry for this file - if (!_FAT_directory_removeEntry (partition, &dirEntry)) { - r->_errno = EIO; - errorOccured = true; - } - - // Flush any sectors in the disc cache - if (!_FAT_cache_flush(partition->cache)) { - r->_errno = EIO; - errorOccured = true; - } - - _FAT_unlock(&partition->lock); - if (errorOccured) { - return -1; - } else { - return 0; - } -} - -int _FAT_chdir_r (struct _reent *r, const char *path) { - PARTITION* partition = NULL; - - // Get the partition this directory is on - partition = _FAT_partition_getPartitionFromPath (path); - if (partition == NULL) { - r->_errno = ENODEV; - return -1; - } - - // Move the path pointer to the start of the actual path - if (strchr (path, ':') != NULL) { - path = strchr (path, ':') + 1; - } - if (strchr (path, ':') != NULL) { - r->_errno = EINVAL; - return -1; - } - - _FAT_lock(&partition->lock); - - // Try changing directory - if (_FAT_directory_chdir (partition, path)) { - // Successful - _FAT_unlock(&partition->lock); - return 0; - } else { - // Failed - _FAT_unlock(&partition->lock); - r->_errno = ENOTDIR; - return -1; - } -} - -int _FAT_rename_r (struct _reent *r, const char *oldName, const char *newName) { - PARTITION* partition = NULL; - DIR_ENTRY oldDirEntry; - DIR_ENTRY newDirEntry; - const char *pathEnd; - uint32_t dirCluster; - - // Get the partition this directory is on - partition = _FAT_partition_getPartitionFromPath (oldName); - if (partition == NULL) { - r->_errno = ENODEV; - return -1; - } - - _FAT_lock(&partition->lock); - - // Make sure the same partition is used for the old and new names - if (partition != _FAT_partition_getPartitionFromPath (newName)) { - _FAT_unlock(&partition->lock); - r->_errno = EXDEV; - return -1; - } - - // Make sure we aren't trying to write to a read-only disc - if (partition->readOnly) { - _FAT_unlock(&partition->lock); - r->_errno = EROFS; - return -1; - } - - // Move the path pointer to the start of the actual path - if (strchr (oldName, ':') != NULL) { - oldName = strchr (oldName, ':') + 1; - } - if (strchr (oldName, ':') != NULL) { - _FAT_unlock(&partition->lock); - r->_errno = EINVAL; - return -1; - } - if (strchr (newName, ':') != NULL) { - newName = strchr (newName, ':') + 1; - } - if (strchr (newName, ':') != NULL) { - _FAT_unlock(&partition->lock); - r->_errno = EINVAL; - return -1; - } - - // Search for the file on the disc - if (!_FAT_directory_entryFromPath (partition, &oldDirEntry, oldName, NULL)) { - _FAT_unlock(&partition->lock); - r->_errno = ENOENT; - return -1; - } - - // Make sure there is no existing file / directory with the new name - if (_FAT_directory_entryFromPath (partition, &newDirEntry, newName, NULL)) { - _FAT_unlock(&partition->lock); - r->_errno = EEXIST; - return -1; - } - - // Create the new file entry - // Get the directory it has to go in - pathEnd = strrchr (newName, DIR_SEPARATOR); - if (pathEnd == NULL) { - // No path was specified - dirCluster = partition->cwdCluster; - pathEnd = newName; - } else { - // Path was specified -- get the right dirCluster - // Recycling newDirEntry, since it needs to be recreated anyway - if (!_FAT_directory_entryFromPath (partition, &newDirEntry, newName, pathEnd) || - !_FAT_directory_isDirectory(&newDirEntry)) { - _FAT_unlock(&partition->lock); - r->_errno = ENOTDIR; - return -1; - } - dirCluster = _FAT_directory_entryGetCluster (partition, newDirEntry.entryData); - // Move the pathEnd past the last DIR_SEPARATOR - pathEnd += 1; - } - - // Copy the entry data - memcpy (&newDirEntry, &oldDirEntry, sizeof(DIR_ENTRY)); - - // Set the new name - strncpy (newDirEntry.filename, pathEnd, MAX_FILENAME_LENGTH - 1); - - // Write the new entry - if (!_FAT_directory_addEntry (partition, &newDirEntry, dirCluster)) { - _FAT_unlock(&partition->lock); - r->_errno = ENOSPC; - return -1; - } - - // Remove the old entry - if (!_FAT_directory_removeEntry (partition, &oldDirEntry)) { - _FAT_unlock(&partition->lock); - r->_errno = EIO; - return -1; - } - - // Flush any sectors in the disc cache - if (!_FAT_cache_flush (partition->cache)) { - _FAT_unlock(&partition->lock); - r->_errno = EIO; - return -1; - } - - _FAT_unlock(&partition->lock); - return 0; -} - -int _FAT_mkdir_r (struct _reent *r, const char *path, int mode) { - PARTITION* partition = NULL; - bool fileExists; - DIR_ENTRY dirEntry; - const char* pathEnd; - uint32_t parentCluster, dirCluster; - uint8_t newEntryData[DIR_ENTRY_DATA_SIZE]; - - partition = _FAT_partition_getPartitionFromPath (path); - if (partition == NULL) { - r->_errno = ENODEV; - return -1; - } - - // Move the path pointer to the start of the actual path - if (strchr (path, ':') != NULL) { - path = strchr (path, ':') + 1; - } - if (strchr (path, ':') != NULL) { - r->_errno = EINVAL; - return -1; - } - - _FAT_lock(&partition->lock); - - // Search for the file/directory on the disc - fileExists = _FAT_directory_entryFromPath (partition, &dirEntry, path, NULL); - - // Make sure it doesn't exist - if (fileExists) { - _FAT_unlock(&partition->lock); - r->_errno = EEXIST; - return -1; - } - - if (partition->readOnly) { - // We can't write to a read-only partition - _FAT_unlock(&partition->lock); - r->_errno = EROFS; - return -1; - } - - // Get the directory it has to go in - pathEnd = strrchr (path, DIR_SEPARATOR); - if (pathEnd == NULL) { - // No path was specified - parentCluster = partition->cwdCluster; - pathEnd = path; - } else { - // Path was specified -- get the right parentCluster - // Recycling dirEntry, since it needs to be recreated anyway - if (!_FAT_directory_entryFromPath (partition, &dirEntry, path, pathEnd) || - !_FAT_directory_isDirectory(&dirEntry)) { - _FAT_unlock(&partition->lock); - r->_errno = ENOTDIR; - return -1; - } - parentCluster = _FAT_directory_entryGetCluster (partition, dirEntry.entryData); - // Move the pathEnd past the last DIR_SEPARATOR - pathEnd += 1; - } - // Create the entry data - strncpy (dirEntry.filename, pathEnd, MAX_FILENAME_LENGTH - 1); - memset (dirEntry.entryData, 0, DIR_ENTRY_DATA_SIZE); - - // Set the creation time and date - dirEntry.entryData[DIR_ENTRY_cTime_ms] = 0; - u16_to_u8array (dirEntry.entryData, DIR_ENTRY_cTime, _FAT_filetime_getTimeFromRTC()); - u16_to_u8array (dirEntry.entryData, DIR_ENTRY_cDate, _FAT_filetime_getDateFromRTC()); - u16_to_u8array (dirEntry.entryData, DIR_ENTRY_mTime, _FAT_filetime_getTimeFromRTC()); - u16_to_u8array (dirEntry.entryData, DIR_ENTRY_mDate, _FAT_filetime_getDateFromRTC()); - u16_to_u8array (dirEntry.entryData, DIR_ENTRY_aDate, _FAT_filetime_getDateFromRTC()); - - // Set the directory attribute - dirEntry.entryData[DIR_ENTRY_attributes] = ATTRIB_DIR; - - // Get a cluster for the new directory - dirCluster = _FAT_fat_linkFreeClusterCleared (partition, CLUSTER_FREE); - if (!_FAT_fat_isValidCluster(partition, dirCluster)) { - // No space left on disc for the cluster - _FAT_unlock(&partition->lock); - r->_errno = ENOSPC; - return -1; - } - u16_to_u8array (dirEntry.entryData, DIR_ENTRY_cluster, dirCluster); - u16_to_u8array (dirEntry.entryData, DIR_ENTRY_clusterHigh, dirCluster >> 16); - - // Write the new directory's entry to it's parent - if (!_FAT_directory_addEntry (partition, &dirEntry, parentCluster)) { - _FAT_unlock(&partition->lock); - r->_errno = ENOSPC; - return -1; - } - - // Create the dot entry within the directory - memset (newEntryData, 0, DIR_ENTRY_DATA_SIZE); - memset (newEntryData, ' ', 11); - newEntryData[DIR_ENTRY_name] = '.'; - newEntryData[DIR_ENTRY_attributes] = ATTRIB_DIR; - u16_to_u8array (newEntryData, DIR_ENTRY_cluster, dirCluster); - u16_to_u8array (newEntryData, DIR_ENTRY_clusterHigh, dirCluster >> 16); - - // Write it to the directory, erasing that sector in the process - _FAT_cache_eraseWritePartialSector ( partition->cache, newEntryData, - _FAT_fat_clusterToSector (partition, dirCluster), 0, DIR_ENTRY_DATA_SIZE); - - - // Create the double dot entry within the directory - - // if ParentDir == Rootdir then ".."" always link to Cluster 0 - if(parentCluster == partition->rootDirCluster) - parentCluster = FAT16_ROOT_DIR_CLUSTER; - - newEntryData[DIR_ENTRY_name + 1] = '.'; - u16_to_u8array (newEntryData, DIR_ENTRY_cluster, parentCluster); - u16_to_u8array (newEntryData, DIR_ENTRY_clusterHigh, parentCluster >> 16); - - // Write it to the directory - _FAT_cache_writePartialSector ( partition->cache, newEntryData, - _FAT_fat_clusterToSector (partition, dirCluster), DIR_ENTRY_DATA_SIZE, DIR_ENTRY_DATA_SIZE); - - // Flush any sectors in the disc cache - if (!_FAT_cache_flush(partition->cache)) { - _FAT_unlock(&partition->lock); - r->_errno = EIO; - return -1; - } - - _FAT_unlock(&partition->lock); - return 0; -} - -int _FAT_statvfs_r (struct _reent *r, const char *path, struct statvfs *buf) -{ - PARTITION* partition = NULL; - unsigned int freeClusterCount; - - // Get the partition of the requested path - partition = _FAT_partition_getPartitionFromPath (path); - if (partition == NULL) { - r->_errno = ENODEV; - return -1; - } - - _FAT_lock(&partition->lock); - - if(memcmp(&buf->f_flag, "SCAN", 4) == 0) - { - //Special command was given to sync the numberFreeCluster - _FAT_partition_createFSinfo(partition); - } - - if(partition->filesysType == FS_FAT32) - freeClusterCount = partition->fat.numberFreeCluster; - else - freeClusterCount = _FAT_fat_freeClusterCount (partition); - - // FAT clusters = POSIX blocks - buf->f_bsize = partition->bytesPerCluster; // File system block size. - buf->f_frsize = partition->bytesPerCluster; // Fundamental file system block size. - - buf->f_blocks = partition->fat.lastCluster - CLUSTER_FIRST + 1; // Total number of blocks on file system in units of f_frsize. - buf->f_bfree = freeClusterCount; // Total number of free blocks. - buf->f_bavail = freeClusterCount; // Number of free blocks available to non-privileged process. - - // Treat requests for info on inodes as clusters - buf->f_files = partition->fat.lastCluster - CLUSTER_FIRST + 1; // Total number of file serial numbers. - buf->f_ffree = freeClusterCount; // Total number of free file serial numbers. - buf->f_favail = freeClusterCount; // Number of file serial numbers available to non-privileged process. - - // File system ID. 32bit ioType value - buf->f_fsid = _FAT_disc_hostType(partition->disc); - - // Bit mask of f_flag values. - buf->f_flag = ST_NOSUID /* No support for ST_ISUID and ST_ISGID file mode bits */ - | (partition->readOnly ? ST_RDONLY /* Read only file system */ : 0 ) ; - // Maximum filename length. - buf->f_namemax = MAX_FILENAME_LENGTH; - - _FAT_unlock(&partition->lock); - return 0; -} - -DIR_ITER* _FAT_diropen_r(struct _reent *r, DIR_ITER *dirState, const char *path) { - DIR_ENTRY dirEntry; - DIR_STATE_STRUCT* state = (DIR_STATE_STRUCT*) (dirState->dirStruct); - bool fileExists; - - state->partition = _FAT_partition_getPartitionFromPath (path); - if (state->partition == NULL) { - r->_errno = ENODEV; - return NULL; - } - - // Move the path pointer to the start of the actual path - if (strchr (path, ':') != NULL) { - path = strchr (path, ':') + 1; - } - if (strchr (path, ':') != NULL) { - r->_errno = EINVAL; - return NULL; - } - - _FAT_lock(&state->partition->lock); - - // Get the start cluster of the directory - fileExists = _FAT_directory_entryFromPath (state->partition, &dirEntry, path, NULL); - - if (!fileExists) { - _FAT_unlock(&state->partition->lock); - r->_errno = ENOENT; - return NULL; - } - - // Make sure it is a directory - if (! _FAT_directory_isDirectory (&dirEntry)) { - _FAT_unlock(&state->partition->lock); - r->_errno = ENOTDIR; - return NULL; - } - - // Save the start cluster for use when resetting the directory data - state->startCluster = _FAT_directory_entryGetCluster (state->partition, dirEntry.entryData); - - // Get the first entry for use with a call to dirnext - state->validEntry = - _FAT_directory_getFirstEntry (state->partition, &(state->currentEntry), state->startCluster); - - // We are now using this entry - state->inUse = true; - _FAT_unlock(&state->partition->lock); - return (DIR_ITER*) state; -} - -int _FAT_dirreset_r (struct _reent *r, DIR_ITER *dirState) { - DIR_STATE_STRUCT* state = (DIR_STATE_STRUCT*) (dirState->dirStruct); - - _FAT_lock(&state->partition->lock); - - // Make sure we are still using this entry - if (!state->inUse) { - _FAT_unlock(&state->partition->lock); - r->_errno = EBADF; - return -1; - } - - // Get the first entry for use with a call to dirnext - state->validEntry = - _FAT_directory_getFirstEntry (state->partition, &(state->currentEntry), state->startCluster); - - _FAT_unlock(&state->partition->lock); - return 0; -} - -int _FAT_dirnext_r (struct _reent *r, DIR_ITER *dirState, char *filename, struct stat *filestat) { - DIR_STATE_STRUCT* state = (DIR_STATE_STRUCT*) (dirState->dirStruct); - - _FAT_lock(&state->partition->lock); - - // Make sure we are still using this entry - if (!state->inUse) { - _FAT_unlock(&state->partition->lock); - r->_errno = EBADF; - return -1; - } - - // Make sure there is another file to report on - if (! state->validEntry) { - _FAT_unlock(&state->partition->lock); - r->_errno = ENOENT; - return -1; - } - - // Get the filename - strncpy (filename, state->currentEntry.filename, MAX_FILENAME_LENGTH); - // Get the stats, if requested - if (filestat != NULL) { - _FAT_directory_entryStat (state->partition, &(state->currentEntry), filestat); - } - - // Look for the next entry for use next time - state->validEntry = - _FAT_directory_getNextEntry (state->partition, &(state->currentEntry)); - - _FAT_unlock(&state->partition->lock); - return 0; -} - -int _FAT_dirclose_r (struct _reent *r, DIR_ITER *dirState) { - DIR_STATE_STRUCT* state = (DIR_STATE_STRUCT*) (dirState->dirStruct); - - // We are no longer using this entry - _FAT_lock(&state->partition->lock); - state->inUse = false; - _FAT_unlock(&state->partition->lock); - - return 0; -} diff --git a/cube/libfat-frag/src/source/fatdir.h b/cube/libfat-frag/src/source/fatdir.h deleted file mode 100644 index 426dd30b..00000000 --- a/cube/libfat-frag/src/source/fatdir.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - fatdir.h - - Functions used by the newlib disc stubs to interface with - this library - - Copyright (c) 2006 Michael "Chishm" Chisholm - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#ifndef _FATDIR_H -#define _FATDIR_H - -#include -#include -#include -#include -#include "common.h" -#include "directory.h" - -typedef struct { - PARTITION* partition; - DIR_ENTRY currentEntry; - uint32_t startCluster; - bool inUse; - bool validEntry; -} DIR_STATE_STRUCT; - -extern int _FAT_stat_r (struct _reent *r, const char *path, struct stat *st); - -extern int _FAT_link_r (struct _reent *r, const char *existing, const char *newLink); - -extern int _FAT_unlink_r (struct _reent *r, const char *name); - -extern int _FAT_chdir_r (struct _reent *r, const char *name); - -extern int _FAT_rename_r (struct _reent *r, const char *oldName, const char *newName); - -extern int _FAT_mkdir_r (struct _reent *r, const char *path, int mode); - -extern int _FAT_statvfs_r (struct _reent *r, const char *path, struct statvfs *buf); - -/* -Directory iterator functions -*/ -extern DIR_ITER* _FAT_diropen_r(struct _reent *r, DIR_ITER *dirState, const char *path); -extern int _FAT_dirreset_r (struct _reent *r, DIR_ITER *dirState); -extern int _FAT_dirnext_r (struct _reent *r, DIR_ITER *dirState, char *filename, struct stat *filestat); -extern int _FAT_dirclose_r (struct _reent *r, DIR_ITER *dirState); - - -#endif // _FATDIR_H diff --git a/cube/libfat-frag/src/source/fatfile.c b/cube/libfat-frag/src/source/fatfile.c deleted file mode 100644 index 17321a5c..00000000 --- a/cube/libfat-frag/src/source/fatfile.c +++ /dev/null @@ -1,1259 +0,0 @@ -/* - fatfile.c - - Functions used by the newlib disc stubs to interface with - this library - - Copyright (c) 2006 Michael "Chishm" Chisholm - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - 2009-10-23 oggzee: fixes for cluster aligned file size (write, truncate, seek) -*/ - - -#include "fatfile.h" - -#include -#include -#include -#include -#include - -#include "cache.h" -#include "file_allocation_table.h" -#include "bit_ops.h" -#include "filetime.h" -#include "lock.h" - -bool _FAT_findEntry(const char *path, DIR_ENTRY *dirEntry) { - PARTITION *partition = _FAT_partition_getPartitionFromPath(path); - - // Move the path pointer to the start of the actual path - if (strchr (path, ':') != NULL) { - path = strchr (path, ':') + 1; - } - if (strchr (path, ':') != NULL) { - return false; - } - - // Search for the file on the disc - return _FAT_directory_entryFromPath (partition, dirEntry, path, NULL); - -} - -int FAT_getAttr(const char *file) { - DIR_ENTRY dirEntry; - if (!_FAT_findEntry(file,&dirEntry)) return -1; - - return dirEntry.entryData[DIR_ENTRY_attributes]; -} - -int FAT_setAttr(const char *file, int attr) { - - // Defines... - DIR_ENTRY_POSITION entryEnd; - PARTITION *partition = NULL; - DIR_ENTRY* dirEntry = NULL; - - // Get Partition - partition = _FAT_partition_getPartitionFromPath( file ); - - // Check Partition - if( !partition ) - return -1; - - // Move the path pointer to the start of the actual path - if (strchr (file, ':') != NULL) - file = strchr (file, ':') + 1; - if (strchr (file, ':') != NULL) - return -1; - - // Get DIR_ENTRY - if( !_FAT_directory_entryFromPath (partition, dirEntry, file, NULL) ) - return -1; - - // Get Entry-End - entryEnd = dirEntry->dataEnd; - - // Lock Partition - _FAT_lock(&partition->lock); - - - // Write Data - _FAT_cache_writePartialSector ( - partition->cache // Cache to write - , &attr // Value to be written - , _FAT_fat_clusterToSector( partition , entryEnd.cluster ) + entryEnd.sector // cluster - , entryEnd.offset * DIR_ENTRY_DATA_SIZE + DIR_ENTRY_attributes // offset - , 1 // Size in bytes - ); - - // Flush any sectors in the disc cache - if ( !_FAT_cache_flush( partition->cache ) ) { - _FAT_unlock(&partition->lock); // Unlock Partition - return -1; - } - - // Unlock Partition - _FAT_unlock(&partition->lock); - - return 0; -} - - -int _FAT_open_r (struct _reent *r, void *fileStruct, const char *path, int flags, int mode) { - PARTITION* partition = NULL; - bool fileExists; - DIR_ENTRY dirEntry; - const char* pathEnd; - uint32_t dirCluster; - FILE_STRUCT* file = (FILE_STRUCT*) fileStruct; - partition = _FAT_partition_getPartitionFromPath (path); - - if (partition == NULL) { - r->_errno = ENODEV; - return -1; - } - - // Move the path pointer to the start of the actual path - if (strchr (path, ':') != NULL) { - path = strchr (path, ':') + 1; - } - if (strchr (path, ':') != NULL) { - r->_errno = EINVAL; - return -1; - } - - // Determine which mode the file is openned for - if ((flags & 0x03) == O_RDONLY) { - // Open the file for read-only access - file->read = true; - file->write = false; - file->append = false; - } else if ((flags & 0x03) == O_WRONLY) { - // Open file for write only access - file->read = false; - file->write = true; - file->append = false; - } else if ((flags & 0x03) == O_RDWR) { - // Open file for read/write access - file->read = true; - file->write = true; - file->append = false; - } else { - r->_errno = EACCES; - return -1; - } - - // Make sure we aren't trying to write to a read-only disc - if (file->write && partition->readOnly) { - r->_errno = EROFS; - return -1; - } - - // Search for the file on the disc - _FAT_lock(&partition->lock); - fileExists = _FAT_directory_entryFromPath (partition, &dirEntry, path, NULL); - - // The file shouldn't exist if we are trying to create it - if ((flags & O_CREAT) && (flags & O_EXCL) && fileExists) { - _FAT_unlock(&partition->lock); - r->_errno = EEXIST; - return -1; - } - - // It should not be a directory if we're openning a file, - if (fileExists && _FAT_directory_isDirectory(&dirEntry)) { - _FAT_unlock(&partition->lock); - r->_errno = EISDIR; - return -1; - } - - // We haven't modified the file yet - file->modified = false; - - // If the file doesn't exist, create it if we're allowed to - if (!fileExists) { - if (flags & O_CREAT) { - if (partition->readOnly) { - // We can't write to a read-only partition - _FAT_unlock(&partition->lock); - r->_errno = EROFS; - return -1; - } - // Create the file - // Get the directory it has to go in - pathEnd = strrchr (path, DIR_SEPARATOR); - if (pathEnd == NULL) { - // No path was specified - dirCluster = partition->cwdCluster; - pathEnd = path; - } else { - // Path was specified -- get the right dirCluster - // Recycling dirEntry, since it needs to be recreated anyway - if (!_FAT_directory_entryFromPath (partition, &dirEntry, path, pathEnd) || - !_FAT_directory_isDirectory(&dirEntry)) { - _FAT_unlock(&partition->lock); - r->_errno = ENOTDIR; - return -1; - } - dirCluster = _FAT_directory_entryGetCluster (partition, dirEntry.entryData); - // Move the pathEnd past the last DIR_SEPARATOR - pathEnd += 1; - } - // Create the entry data - strncpy (dirEntry.filename, pathEnd, MAX_FILENAME_LENGTH - 1); - memset (dirEntry.entryData, 0, DIR_ENTRY_DATA_SIZE); - - // Set the creation time and date - dirEntry.entryData[DIR_ENTRY_cTime_ms] = 0; - u16_to_u8array (dirEntry.entryData, DIR_ENTRY_cTime, _FAT_filetime_getTimeFromRTC()); - u16_to_u8array (dirEntry.entryData, DIR_ENTRY_cDate, _FAT_filetime_getDateFromRTC()); - - if (!_FAT_directory_addEntry (partition, &dirEntry, dirCluster)) { - _FAT_unlock(&partition->lock); - r->_errno = ENOSPC; - return -1; - } - - // File entry is modified - file->modified = true; - } else { - // file doesn't exist, and we aren't creating it - _FAT_unlock(&partition->lock); - r->_errno = ENOENT; - return -1; - } - } - - file->filesize = u8array_to_u32 (dirEntry.entryData, DIR_ENTRY_fileSize); - - /* Allow LARGEFILEs with undefined results - // Make sure that the file size can fit in the available space - if (!(flags & O_LARGEFILE) && (file->filesize >= (1<<31))) { - r->_errno = EFBIG; - return -1; - } - */ - - // Make sure we aren't trying to write to a read-only file - if (file->write && !_FAT_directory_isWritable(&dirEntry)) { - _FAT_unlock(&partition->lock); - r->_errno = EROFS; - return -1; - } - - // Associate this file with a particular partition - file->partition = partition; - - file->startCluster = _FAT_directory_entryGetCluster (partition, dirEntry.entryData); - - // Truncate the file if requested - if ((flags & O_TRUNC) && file->write && (file->startCluster != 0)) { - _FAT_fat_clearLinks (partition, file->startCluster); - file->startCluster = CLUSTER_FREE; - file->filesize = 0; - // File is modified since we just cut it all off - file->modified = true; - } - - // Remember the position of this file's directory entry - file->dirEntryStart = dirEntry.dataStart; // Points to the start of the LFN entries of a file, or the alias for no LFN - file->dirEntryEnd = dirEntry.dataEnd; - - // Reset read/write pointer - file->currentPosition = 0; - file->rwPosition.cluster = file->startCluster; - file->rwPosition.sector = 0; - file->rwPosition.byte = 0; - - if (flags & O_APPEND) { - file->append = true; - - // Set append pointer to the end of the file - file->appendPosition.cluster = _FAT_fat_lastCluster (partition, file->startCluster); - file->appendPosition.sector = (file->filesize % partition->bytesPerCluster) / partition->bytesPerSector; - file->appendPosition.byte = file->filesize % partition->bytesPerSector; - - // Check if the end of the file is on the end of a cluster - if ( (file->filesize > 0) && ((file->filesize % partition->bytesPerCluster)==0) ){ - // Set flag to allocate a new cluster - file->appendPosition.sector = partition->sectorsPerCluster; - file->appendPosition.byte = 0; - } - } else { - file->append = false; - // Use something sane for the append pointer, so the whole file struct contains known values - file->appendPosition = file->rwPosition; - } - - file->inUse = true; - - // Insert this file into the double-linked list of open files - partition->openFileCount += 1; - if (partition->firstOpenFile) { - file->nextOpenFile = partition->firstOpenFile; - partition->firstOpenFile->prevOpenFile = file; - } else { - file->nextOpenFile = NULL; - } - file->prevOpenFile = NULL; - partition->firstOpenFile = file; - - _FAT_unlock(&partition->lock); - - return (int) file; -} - -/* -Synchronizes the file data to disc. -Does no locking of its own -- lock the partition before calling. -Returns 0 on success, an error code on failure. -*/ -int _FAT_syncToDisc (FILE_STRUCT* file) { - uint8_t dirEntryData[DIR_ENTRY_DATA_SIZE]; - - if (!file || !file->inUse) { - return EBADF; - } - - if (file->write && file->modified) { - // Load the old entry - _FAT_cache_readPartialSector (file->partition->cache, dirEntryData, - _FAT_fat_clusterToSector(file->partition, file->dirEntryEnd.cluster) + file->dirEntryEnd.sector, - file->dirEntryEnd.offset * DIR_ENTRY_DATA_SIZE, DIR_ENTRY_DATA_SIZE); - - // Write new data to the directory entry - // File size - u32_to_u8array (dirEntryData, DIR_ENTRY_fileSize, file->filesize); - - // Start cluster - u16_to_u8array (dirEntryData, DIR_ENTRY_cluster, file->startCluster); - u16_to_u8array (dirEntryData, DIR_ENTRY_clusterHigh, file->startCluster >> 16); - - // Modification time and date - u16_to_u8array (dirEntryData, DIR_ENTRY_mTime, _FAT_filetime_getTimeFromRTC()); - u16_to_u8array (dirEntryData, DIR_ENTRY_mDate, _FAT_filetime_getDateFromRTC()); - - // Access date - u16_to_u8array (dirEntryData, DIR_ENTRY_aDate, _FAT_filetime_getDateFromRTC()); - - // Set archive attribute - dirEntryData[DIR_ENTRY_attributes] |= ATTRIB_ARCH; - - // Write the new entry - _FAT_cache_writePartialSector (file->partition->cache, dirEntryData, - _FAT_fat_clusterToSector(file->partition, file->dirEntryEnd.cluster) + file->dirEntryEnd.sector, - file->dirEntryEnd.offset * DIR_ENTRY_DATA_SIZE, DIR_ENTRY_DATA_SIZE); - - // Flush any sectors in the disc cache - if (!_FAT_cache_flush(file->partition->cache)) { - return EIO; - } - } - - file->modified = false; - - return 0; -} - - -int _FAT_close_r (struct _reent *r, int fd) { - FILE_STRUCT* file = (FILE_STRUCT*) fd; - int ret = 0; - - if (!file->inUse) { - r->_errno = EBADF; - return -1; - } - - _FAT_lock(&file->partition->lock); - - if (file->write) { - ret = _FAT_syncToDisc (file); - if (ret != 0) { - r->_errno = ret; - ret = -1; - } - } - - file->inUse = false; - - // Remove this file from the double-linked list of open files - file->partition->openFileCount -= 1; - if (file->nextOpenFile) { - file->nextOpenFile->prevOpenFile = file->prevOpenFile; - } - if (file->prevOpenFile) { - file->prevOpenFile->nextOpenFile = file->nextOpenFile; - } else { - file->partition->firstOpenFile = file->nextOpenFile; - } - - _FAT_unlock(&file->partition->lock); - - return ret; -} - -ssize_t _FAT_read_r (struct _reent *r, int fd, char *ptr, size_t len) { - FILE_STRUCT* file = (FILE_STRUCT*) fd; - PARTITION* partition; - CACHE* cache; - FILE_POSITION position; - uint32_t tempNextCluster; - unsigned int tempVar; - size_t remain; - bool flagNoError = true; - - // Short circuit cases where len is 0 (or less) - if (len <= 0) { - return 0; - } - - // Make sure we can actually read from the file - if ((file == NULL) || !file->inUse || !file->read) { - r->_errno = EBADF; - return -1; - } - - partition = file->partition; - _FAT_lock(&partition->lock); - - // Don't try to read if the read pointer is past the end of file - if (file->currentPosition >= file->filesize || file->startCluster == CLUSTER_FREE) { - r->_errno = EOVERFLOW; - _FAT_unlock(&partition->lock); - return 0; - } - - // Don't read past end of file - if (len + file->currentPosition > file->filesize) { - r->_errno = EOVERFLOW; - len = file->filesize - file->currentPosition; - } - - remain = len; - position = file->rwPosition; - cache = file->partition->cache; - - // Align to sector - tempVar = partition->bytesPerSector - position.byte; - if (tempVar > remain) { - tempVar = remain; - } - - if ((tempVar < partition->bytesPerSector) && flagNoError) - { - _FAT_cache_readPartialSector ( cache, ptr, _FAT_fat_clusterToSector (partition, position.cluster) + position.sector, - position.byte, tempVar); - - remain -= tempVar; - ptr += tempVar; - - position.byte += tempVar; - if (position.byte >= partition->bytesPerSector) { - position.byte = 0; - position.sector++; - } - } - - // align to cluster - // tempVar is number of sectors to read - if (remain > (partition->sectorsPerCluster - position.sector) * partition->bytesPerSector) { - tempVar = partition->sectorsPerCluster - position.sector; - } else { - tempVar = remain / partition->bytesPerSector; - } - - if ((tempVar > 0) && flagNoError) { - if (! _FAT_cache_readSectors (cache, _FAT_fat_clusterToSector (partition, position.cluster) + position.sector, - tempVar, ptr)) - { - flagNoError = false; - r->_errno = EIO; - } else { - ptr += tempVar * partition->bytesPerSector; - remain -= tempVar * partition->bytesPerSector; - position.sector += tempVar; - } - } - - // Move onto next cluster - // It should get to here without reading anything if a cluster is due to be allocated - if ((position.sector >= partition->sectorsPerCluster) && flagNoError) { - tempNextCluster = _FAT_fat_nextCluster(partition, position.cluster); - if ((remain == 0) && (tempNextCluster == CLUSTER_EOF)) { - position.sector = partition->sectorsPerCluster; - } else if (!_FAT_fat_isValidCluster(partition, tempNextCluster)) { - r->_errno = EIO; - flagNoError = false; - } else { - position.sector = 0; - position.cluster = tempNextCluster; - } - } - - // Read in whole clusters, contiguous blocks at a time - while ((remain >= partition->bytesPerCluster) && flagNoError) { - uint32_t chunkEnd; - uint32_t nextChunkStart = position.cluster; - size_t chunkSize = 0; - - do { - chunkEnd = nextChunkStart; - nextChunkStart = _FAT_fat_nextCluster (partition, chunkEnd); - chunkSize += partition->bytesPerCluster; - } while ((nextChunkStart == chunkEnd + 1) && -#ifdef LIMIT_SECTORS - (chunkSize + partition->bytesPerCluster <= LIMIT_SECTORS * partition->bytesPerSector) && -#endif - (chunkSize + partition->bytesPerCluster <= remain)); - - if (!_FAT_cache_readSectors (cache, _FAT_fat_clusterToSector (partition, position.cluster), - chunkSize / partition->bytesPerSector, ptr)) - { - flagNoError = false; - r->_errno = EIO; - break; - } - ptr += chunkSize; - remain -= chunkSize; - - // Advance to next cluster - if ((remain == 0) && (nextChunkStart == CLUSTER_EOF)) { - position.sector = partition->sectorsPerCluster; - position.cluster = chunkEnd; - } else if (!_FAT_fat_isValidCluster(partition, nextChunkStart)) { - r->_errno = EIO; - flagNoError = false; - } else { - position.sector = 0; - position.cluster = nextChunkStart; - } - } - - // Read remaining sectors - tempVar = remain / partition->bytesPerSector; // Number of sectors left - if ((tempVar > 0) && flagNoError) { - if (!_FAT_cache_readSectors (cache, _FAT_fat_clusterToSector (partition, position.cluster), - tempVar, ptr)) - { - flagNoError = false; - r->_errno = EIO; - } else { - ptr += tempVar * partition->bytesPerSector; - remain -= tempVar * partition->bytesPerSector; - position.sector += tempVar; - } - } - - // Last remaining sector - // Check if anything is left - if ((remain > 0) && flagNoError) { - _FAT_cache_readPartialSector ( cache, ptr, - _FAT_fat_clusterToSector (partition, position.cluster) + position.sector, 0, remain); - position.byte += remain; - remain = 0; - } - - // Length read is the wanted length minus the stuff not read - len = len - remain; - - // Update file information - file->rwPosition = position; - file->currentPosition += len; - - _FAT_unlock(&partition->lock); - return len; -} - -// if current position is on the cluster border and more data has to be written -// then get next cluster or allocate next cluster -// this solves the over-allocation problems when file size is aligned to cluster size -// return true on succes, false on error -static bool _FAT_check_position_for_next_cluster(struct _reent *r, - FILE_POSITION *position, PARTITION* partition, size_t remain, bool *flagNoError) -{ - uint32_t tempNextCluster; - // do nothing if no more data to write - if (remain == 0) return true; - if (flagNoError && *flagNoError == false) return false; - if ((remain < 0) || (position->sector > partition->sectorsPerCluster)) { - // invalid arguments - internal error - r->_errno = EINVAL; - goto err; - } - if (position->sector == partition->sectorsPerCluster) { - // need to advance to next cluster - tempNextCluster = _FAT_fat_nextCluster(partition, position->cluster); - if ((tempNextCluster == CLUSTER_EOF) || (tempNextCluster == CLUSTER_FREE)) { - // Ran out of clusters so get a new one - tempNextCluster = _FAT_fat_linkFreeCluster(partition, position->cluster); - } - if (!_FAT_fat_isValidCluster(partition, tempNextCluster)) { - // Couldn't get a cluster, so abort - r->_errno = ENOSPC; - goto err; - } - position->sector = 0; - position->cluster = tempNextCluster; - } - return true; -err: - if (flagNoError) *flagNoError = false; - return false; -} - -/* -Extend a file so that the size is the same as the rwPosition -*/ -static bool _FAT_file_extend_r (struct _reent *r, FILE_STRUCT* file) { - PARTITION* partition = file->partition; - CACHE* cache = file->partition->cache; - FILE_POSITION position; - uint8_t zeroBuffer [partition->bytesPerSector]; - memset(zeroBuffer, 0, partition->bytesPerSector); - uint32_t remain; - uint32_t tempNextCluster; - unsigned int sector; - - position.byte = file->filesize % partition->bytesPerSector; - position.sector = (file->filesize % partition->bytesPerCluster) / partition->bytesPerSector; - // It is assumed that there is always a startCluster - // This will be true when _FAT_file_extend_r is called from _FAT_write_r - position.cluster = _FAT_fat_lastCluster (partition, file->startCluster); - - remain = file->currentPosition - file->filesize; - - if ((remain > 0) && (file->filesize > 0) && (position.sector == 0) && (position.byte == 0)) { - // Get a new cluster on the edge of a cluster boundary - tempNextCluster = _FAT_fat_linkFreeCluster(partition, position.cluster); - if (!_FAT_fat_isValidCluster(partition, tempNextCluster)) { - // Couldn't get a cluster, so abort - r->_errno = ENOSPC; - return false; - } - position.cluster = tempNextCluster; - position.sector = 0; - } - - if (remain + position.byte < partition->bytesPerSector) { - // Only need to clear to the end of the sector - _FAT_cache_writePartialSector (cache, zeroBuffer, - _FAT_fat_clusterToSector (partition, position.cluster) + position.sector, position.byte, remain); - position.byte += remain; - } else { - if (position.byte > 0) { - _FAT_cache_writePartialSector (cache, zeroBuffer, - _FAT_fat_clusterToSector (partition, position.cluster) + position.sector, position.byte, - partition->bytesPerSector - position.byte); - remain -= (partition->bytesPerSector - position.byte); - position.byte = 0; - position.sector ++; - } - - while (remain >= partition->bytesPerSector) { - if (position.sector >= partition->sectorsPerCluster) { - position.sector = 0; - // Ran out of clusters so get a new one - tempNextCluster = _FAT_fat_linkFreeCluster(partition, position.cluster); - if (!_FAT_fat_isValidCluster(partition, tempNextCluster)) { - // Couldn't get a cluster, so abort - r->_errno = ENOSPC; - return false; - } - position.cluster = tempNextCluster; - } - - sector = _FAT_fat_clusterToSector (partition, position.cluster) + position.sector; - _FAT_cache_writeSectors (cache, sector, 1, zeroBuffer); - - remain -= partition->bytesPerSector; - position.sector ++; - } - - if (!_FAT_check_position_for_next_cluster(r, &position, partition, remain, NULL)) { - // error already marked - return false; - } - - if (remain > 0) { - _FAT_cache_writePartialSector (cache, zeroBuffer, - _FAT_fat_clusterToSector (partition, position.cluster) + position.sector, 0, remain); - position.byte = remain; - } - } - - file->rwPosition = position; - file->filesize = file->currentPosition; - return true; -} - -ssize_t _FAT_write_r (struct _reent *r, int fd, const char *ptr, size_t len) { - FILE_STRUCT* file = (FILE_STRUCT*) fd; - PARTITION* partition; - CACHE* cache; - FILE_POSITION position; - uint32_t tempNextCluster; - unsigned int tempVar; - size_t remain; - bool flagNoError = true; - bool flagAppending = false; - - // Make sure we can actually write to the file - if ((file == NULL) || !file->inUse || !file->write) { - r->_errno = EBADF; - return -1; - } - - partition = file->partition; - cache = file->partition->cache; - _FAT_lock(&partition->lock); - - // Only write up to the maximum file size, taking into account wrap-around of ints - if (len + file->filesize > FILE_MAX_SIZE || len + file->filesize < file->filesize) { - len = FILE_MAX_SIZE - file->filesize; - } - - // Short circuit cases where len is 0 (or less) - if (len <= 0) { - _FAT_unlock(&partition->lock); - return 0; - } - - remain = len; - - // Get a new cluster for the start of the file if required - if (file->startCluster == CLUSTER_FREE) { - tempNextCluster = _FAT_fat_linkFreeCluster (partition, CLUSTER_FREE); - if (!_FAT_fat_isValidCluster(partition, tempNextCluster)) { - // Couldn't get a cluster, so abort immediately - _FAT_unlock(&partition->lock); - r->_errno = ENOSPC; - return -1; - } - file->startCluster = tempNextCluster; - - // Appending starts at the begining for a 0 byte file - file->appendPosition.cluster = file->startCluster; - file->appendPosition.sector = 0; - file->appendPosition.byte = 0; - - file->rwPosition.cluster = file->startCluster; - file->rwPosition.sector = 0; - file->rwPosition.byte = 0; - } - - if (file->append) { - position = file->appendPosition; - flagAppending = true; - } else { - // If the write pointer is past the end of the file, extend the file to that size - if (file->currentPosition > file->filesize) { - if (!_FAT_file_extend_r (r, file)) { - _FAT_unlock(&partition->lock); - return -1; - } - } - - // Write at current read pointer - position = file->rwPosition; - - // If it is writing past the current end of file, set appending flag - if (len + file->currentPosition > file->filesize) { - flagAppending = true; - } - } - - // Move onto next cluster if needed - _FAT_check_position_for_next_cluster(r, &position, partition, remain, &flagNoError); - - // Align to sector - tempVar = partition->bytesPerSector - position.byte; - if (tempVar > remain) { - tempVar = remain; - } - - if ((tempVar < partition->bytesPerSector) && flagNoError) { - // Write partial sector to disk - _FAT_cache_writePartialSector (cache, ptr, - _FAT_fat_clusterToSector (partition, position.cluster) + position.sector, position.byte, tempVar); - - remain -= tempVar; - ptr += tempVar; - position.byte += tempVar; - - - // Move onto next sector - if (position.byte >= partition->bytesPerSector) { - position.byte = 0; - position.sector ++; - } - } - - // Align to cluster - // tempVar is number of sectors to write - if (remain > (partition->sectorsPerCluster - position.sector) * partition->bytesPerSector) { - tempVar = partition->sectorsPerCluster - position.sector; - } else { - tempVar = remain / partition->bytesPerSector; - } - - if ((tempVar > 0 && tempVar < partition->sectorsPerCluster) && flagNoError) { - if (!_FAT_cache_writeSectors (cache, - _FAT_fat_clusterToSector (partition, position.cluster) + position.sector, tempVar, ptr)) - { - flagNoError = false; - r->_errno = EIO; - } else { - ptr += tempVar * partition->bytesPerSector; - remain -= tempVar * partition->bytesPerSector; - position.sector += tempVar; - } - } - - // Write whole clusters - while ((remain >= partition->bytesPerCluster) && flagNoError) { - // allocate next cluster - _FAT_check_position_for_next_cluster(r, &position, partition, remain, &flagNoError); - if (!flagNoError) break; - // set indexes to the current position - uint32_t chunkEnd = position.cluster; - uint32_t nextChunkStart = position.cluster; - size_t chunkSize = partition->bytesPerCluster; - FILE_POSITION next_position = position; - - // group consecutive clusters - while (flagNoError && -#ifdef LIMIT_SECTORS - (chunkSize + partition->bytesPerCluster <= LIMIT_SECTORS * partition->bytesPerSector) && -#endif - (chunkSize + partition->bytesPerCluster < remain)) - { - // pretend to use up all sectors in next_position - next_position.sector = partition->sectorsPerCluster; - // get or allocate next cluster - _FAT_check_position_for_next_cluster(r, &next_position, partition, - remain - chunkSize, &flagNoError); - if (!flagNoError) break; // exit loop on error - nextChunkStart = next_position.cluster; - if (nextChunkStart != chunkEnd + 1) break; // exit loop if not consecutive - chunkEnd = nextChunkStart; - chunkSize += partition->bytesPerCluster; - } - - if ( !_FAT_cache_writeSectors (cache, - _FAT_fat_clusterToSector(partition, position.cluster), chunkSize / partition->bytesPerSector, ptr)) - { - flagNoError = false; - r->_errno = EIO; - break; - } - ptr += chunkSize; - remain -= chunkSize; - - if ((chunkEnd != nextChunkStart) && _FAT_fat_isValidCluster(partition, nextChunkStart)) { - // new cluster is already allocated (because it was not consecutive) - position.cluster = nextChunkStart; - position.sector = 0; - } else { - // Allocate a new cluster when next writing the file - position.cluster = chunkEnd; - position.sector = partition->sectorsPerCluster; - } - } - - // allocate next cluster if needed - _FAT_check_position_for_next_cluster(r, &position, partition, remain, &flagNoError); - - // Write remaining sectors - tempVar = remain / partition->bytesPerSector; // Number of sectors left - if ((tempVar > 0) && flagNoError) { - if (!_FAT_cache_writeSectors (cache, _FAT_fat_clusterToSector (partition, position.cluster), tempVar, ptr)) - { - flagNoError = false; - r->_errno = EIO; - } else { - ptr += tempVar * partition->bytesPerSector; - remain -= tempVar * partition->bytesPerSector; - position.sector += tempVar; - } - } - - // Last remaining sector - if ((remain > 0) && flagNoError) { - if (flagAppending) { - _FAT_cache_eraseWritePartialSector ( cache, ptr, - _FAT_fat_clusterToSector (partition, position.cluster) + position.sector, 0, remain); - } else { - _FAT_cache_writePartialSector ( cache, ptr, - _FAT_fat_clusterToSector (partition, position.cluster) + position.sector, 0, remain); - } - position.byte += remain; - remain = 0; - } - - - // Amount written is the originally requested amount minus stuff remaining - len = len - remain; - - // Update file information - file->modified = true; - if (file->append) { - // Appending doesn't affect the read pointer - file->appendPosition = position; - file->filesize += len; - } else { - // Writing also shifts the read pointer - file->rwPosition = position; - file->currentPosition += len; - if (file->filesize < file->currentPosition) { - file->filesize = file->currentPosition; - } - } - _FAT_unlock(&partition->lock); - - return len; -} - - -off_t _FAT_seek_r (struct _reent *r, int fd, off_t pos, int dir) { - FILE_STRUCT* file = (FILE_STRUCT*) fd; - PARTITION* partition; - uint32_t cluster, nextCluster; - int clusCount; - off_t newPosition; - uint32_t position; - - if ((file == NULL) || (file->inUse == false)) { - // invalid file - r->_errno = EBADF; - return -1; - } - - partition = file->partition; - _FAT_lock(&partition->lock); - - switch (dir) { - case SEEK_SET: - newPosition = pos; - break; - case SEEK_CUR: - newPosition = (off_t)file->currentPosition + pos; - break; - case SEEK_END: - newPosition = (off_t)file->filesize + pos; - break; - default: - _FAT_unlock(&partition->lock); - r->_errno = EINVAL; - return -1; - } - - if ((pos > 0) && (newPosition < 0)) { - _FAT_unlock(&partition->lock); - r->_errno = EOVERFLOW; - return -1; - } - - // newPosition can only be larger than the FILE_MAX_SIZE on platforms where - // off_t is larger than 32 bits. - if (newPosition < 0 || ((sizeof(newPosition) > 4) && newPosition > (off_t)FILE_MAX_SIZE)) { - _FAT_unlock(&partition->lock); - r->_errno = EINVAL; - return -1; - } - - position = (uint32_t)newPosition; - - // Only change the read/write position if it is within the bounds of the current filesize, - // or at the very edge of the file - if (position <= file->filesize && file->startCluster != CLUSTER_FREE) { - // Calculate where the correct cluster is - // how many clusters from start of file - clusCount = position / partition->bytesPerCluster; - cluster = file->startCluster; - if (position >= file->currentPosition) { - // start from current cluster - int currentCount = file->currentPosition / partition->bytesPerCluster; - if (file->rwPosition.sector == partition->sectorsPerCluster) { - currentCount--; - } - clusCount -= currentCount; - cluster = file->rwPosition.cluster; - } - // Calculate the sector and byte of the current position, - // and store them - file->rwPosition.sector = (position % partition->bytesPerCluster) / partition->bytesPerSector; - file->rwPosition.byte = position % partition->bytesPerSector; - - nextCluster = _FAT_fat_nextCluster (partition, cluster); - while ((clusCount > 0) && (nextCluster != CLUSTER_FREE) && (nextCluster != CLUSTER_EOF)) { - clusCount--; - cluster = nextCluster; - nextCluster = _FAT_fat_nextCluster (partition, cluster); - } - - // Check if ran out of clusters and it needs to allocate a new one - if (clusCount > 0) { - if ((clusCount == 1) && (file->filesize == position) && (file->rwPosition.sector == 0)) { - // Set flag to allocate a new cluster - file->rwPosition.sector = partition->sectorsPerCluster; - file->rwPosition.byte = 0; - } else { - _FAT_unlock(&partition->lock); - r->_errno = EINVAL; - return -1; - } - } - - file->rwPosition.cluster = cluster; - } - - // Save position - file->currentPosition = position; - - _FAT_unlock(&partition->lock); - return position; -} - - - -int _FAT_fstat_r (struct _reent *r, int fd, struct stat *st) { - FILE_STRUCT* file = (FILE_STRUCT*) fd; - PARTITION* partition; - DIR_ENTRY fileEntry; - - if ((file == NULL) || (file->inUse == false)) { - // invalid file - r->_errno = EBADF; - return -1; - } - - partition = file->partition; - _FAT_lock(&partition->lock); - - // Get the file's entry data - fileEntry.dataStart = file->dirEntryStart; - fileEntry.dataEnd = file->dirEntryEnd; - - if (!_FAT_directory_entryFromPosition (partition, &fileEntry)) { - _FAT_unlock(&partition->lock); - r->_errno = EIO; - return -1; - } - - // Fill in the stat struct - _FAT_directory_entryStat (partition, &fileEntry, st); - - // Fix stats that have changed since the file was openned - st->st_ino = (ino_t)(file->startCluster); // The file serial number is the start cluster - st->st_size = file->filesize; // File size - - _FAT_unlock(&partition->lock); - return 0; -} - -int _FAT_ftruncate_r (struct _reent *r, int fd, off_t len) { - FILE_STRUCT* file = (FILE_STRUCT*) fd; - PARTITION* partition; - int ret=0; - uint32_t newSize = (uint32_t)len; - - if (len < 0) { - // Trying to truncate to a negative size - r->_errno = EINVAL; - return -1; - } - - if ((sizeof(len) > 4) && len > (off_t)FILE_MAX_SIZE) { - // Trying to extend the file beyond what FAT supports - r->_errno = EFBIG; - return -1; - } - - if (!file || !file->inUse) { - // invalid file - r->_errno = EBADF; - return -1; - } - - if (!file->write) { - // Read-only file - r->_errno = EINVAL; - return -1; - } - - partition = file->partition; - _FAT_lock(&partition->lock); - - if (newSize > file->filesize) { - // Expanding the file - FILE_POSITION savedPosition; - uint32_t savedOffset; - // Get a new cluster for the start of the file if required - if (file->startCluster == CLUSTER_FREE) { - uint32_t tempNextCluster = _FAT_fat_linkFreeCluster (partition, CLUSTER_FREE); - if (!_FAT_fat_isValidCluster(partition, tempNextCluster)) { - // Couldn't get a cluster, so abort immediately - _FAT_unlock(&partition->lock); - r->_errno = ENOSPC; - return -1; - } - file->startCluster = tempNextCluster; - - file->rwPosition.cluster = file->startCluster; - file->rwPosition.sector = 0; - file->rwPosition.byte = 0; - } - // Save the read/write pointer - savedPosition = file->rwPosition; - savedOffset = file->currentPosition; - // Set the position to the new size - file->currentPosition = newSize; - // Extend the file to the new position - if (!_FAT_file_extend_r (r, file)) { - ret = -1; - } - // Set the append position to the new rwPointer - if (file->append) { - file->appendPosition = file->rwPosition; - } - // Restore the old rwPointer; - file->rwPosition = savedPosition; - file->currentPosition = savedOffset; - } else if (newSize < file->filesize){ - // Shrinking the file - if (len == 0) { - // Cutting the file down to nothing, clear all clusters used - _FAT_fat_clearLinks (partition, file->startCluster); - file->startCluster = CLUSTER_FREE; - - file->appendPosition.cluster = CLUSTER_FREE; - file->appendPosition.sector = 0; - file->appendPosition.byte = 0; - } else { - // Trimming the file down to the required size - unsigned int chainLength; - uint32_t lastCluster; - - // Drop the unneeded end of the cluster chain. - // If the end falls on a cluster boundary, drop that cluster too, - // then set a flag to allocate a cluster as needed - chainLength = ((newSize-1) / partition->bytesPerCluster) + 1; - lastCluster = _FAT_fat_trimChain (partition, file->startCluster, chainLength); - - if (file->append) { - file->appendPosition.byte = newSize % partition->bytesPerSector; - // Does the end of the file fall on the edge of a cluster? - if (newSize % partition->bytesPerCluster == 0) { - // Set a flag to allocate a new cluster - file->appendPosition.sector = partition->sectorsPerCluster; - } else { - file->appendPosition.sector = (newSize % partition->bytesPerCluster) / partition->bytesPerSector; - } - file->appendPosition.cluster = lastCluster; - } - } - } else { - // Truncating to same length, so don't do anything - } - - file->filesize = newSize; - file->modified = true; - - _FAT_unlock(&partition->lock); - return ret; -} - -int _FAT_fsync_r (struct _reent *r, int fd) { - FILE_STRUCT* file = (FILE_STRUCT*) fd; - int ret = 0; - - if (!file->inUse) { - r->_errno = EBADF; - return -1; - } - - _FAT_lock(&file->partition->lock); - - ret = _FAT_syncToDisc (file); - if (ret != 0) { - r->_errno = ret; - ret = -1; - } - - _FAT_unlock(&file->partition->lock); - - return ret; -} -typedef int (*_frag_append_t)(void *ff, u32 offset, u32 sector, u32 count); - -int _FAT_get_fragments (const char *path, _frag_append_t append_fragment, void *callback_data) -{ - struct _reent r; - FILE_STRUCT file; - PARTITION* partition; - u32 cluster; - u32 sector; - u32 offset; // in sectors - u32 size; // in sectors - int ret = -1; - int fd; - - fd = _FAT_open_r (&r, &file, path, O_RDONLY, 0); - if (fd == -1) return -1; - if (fd != (int)&file) return -1; - - partition = file.partition; - _FAT_lock(&partition->lock); - - size = file.filesize / 512; - cluster = file.startCluster; - offset = 0; - - do { - if (!_FAT_fat_isValidCluster(partition, cluster)) { - // invalid cluster - goto out; - } - // add cluster to fileinfo - sector = _FAT_fat_clusterToSector(partition, cluster); - if (append_fragment(callback_data, offset, sector, partition->sectorsPerCluster)) { - // too many fragments - goto out; - } - offset += partition->sectorsPerCluster; - cluster = _FAT_fat_nextCluster (partition, cluster); - } while (offset < size); - - // set size - append_fragment(callback_data, size, 0, 0); - // success - ret = 0; - - out: - _FAT_unlock(&partition->lock); - _FAT_close_r(&r, fd); - return ret; -} diff --git a/cube/libfat-frag/src/source/fatfile.h b/cube/libfat-frag/src/source/fatfile.h deleted file mode 100644 index 5e4648df..00000000 --- a/cube/libfat-frag/src/source/fatfile.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - fatfile.h - - Functions used by the newlib disc stubs to interface with - this library - - Copyright (c) 2006 Michael "Chishm" Chisholm - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#ifndef _FATFILE_H -#define _FATFILE_H - -#include -#include - -#include "common.h" -#include "partition.h" -#include "directory.h" - -#define FILE_MAX_SIZE ((uint32_t)0xFFFFFFFF) // 4GiB - 1B - -typedef struct { - u32 cluster; - sec_t sector; - s32 byte; -} FILE_POSITION; - -struct _FILE_STRUCT; - -struct _FILE_STRUCT { - uint32_t filesize; - uint32_t startCluster; - uint32_t currentPosition; - FILE_POSITION rwPosition; - FILE_POSITION appendPosition; - DIR_ENTRY_POSITION dirEntryStart; // Points to the start of the LFN entries of a file, or the alias for no LFN - DIR_ENTRY_POSITION dirEntryEnd; // Always points to the file's alias entry - PARTITION* partition; - struct _FILE_STRUCT* prevOpenFile; // The previous entry in a double-linked list of open files - struct _FILE_STRUCT* nextOpenFile; // The next entry in a double-linked list of open files - bool read; - bool write; - bool append; - bool inUse; - bool modified; -}; - -typedef struct _FILE_STRUCT FILE_STRUCT; - -int _FAT_open_r (struct _reent *r, void *fileStruct, const char *path, int flags, int mode); - -int _FAT_close_r (struct _reent *r, int fd); - -ssize_t _FAT_write_r (struct _reent *r,int fd, const char *ptr, size_t len); - -ssize_t _FAT_read_r (struct _reent *r, int fd, char *ptr, size_t len); - -off_t _FAT_seek_r (struct _reent *r, int fd, off_t pos, int dir); - -int _FAT_fstat_r (struct _reent *r, int fd, struct stat *st); - -int _FAT_stat_r (struct _reent *r, const char *path, struct stat *st); - -int _FAT_link_r (struct _reent *r, const char *existing, const char *newLink); - -int _FAT_unlink_r (struct _reent *r, const char *name); - -int _FAT_chdir_r (struct _reent *r, const char *name); - -int _FAT_rename_r (struct _reent *r, const char *oldName, const char *newName); - -int _FAT_ftruncate_r (struct _reent *r, int fd, off_t len); - -int _FAT_fsync_r (struct _reent *r, int fd); - -/* -Synchronizes the file data to disc. -Does no locking of its own -- lock the partition before calling. -Returns 0 on success, an error code on failure. -*/ -extern int _FAT_syncToDisc (FILE_STRUCT* file); - -#endif // _FATFILE_H diff --git a/cube/libfat-frag/src/source/file_allocation_table.c b/cube/libfat-frag/src/source/file_allocation_table.c deleted file mode 100644 index 72f8aa74..00000000 --- a/cube/libfat-frag/src/source/file_allocation_table.c +++ /dev/null @@ -1,393 +0,0 @@ -/* - file_allocation_table.c - Reading, writing and manipulation of the FAT structure on - a FAT partition - - Copyright (c) 2006 Michael "Chishm" Chisholm - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include "file_allocation_table.h" -#include "partition.h" -#include "mem_allocate.h" -#include - -/* -Gets the cluster linked from input cluster -*/ -uint32_t _FAT_fat_nextCluster(PARTITION* partition, uint32_t cluster) -{ - uint32_t nextCluster = CLUSTER_FREE; - sec_t sector; - int offset; - - if (cluster == CLUSTER_FREE) { - return CLUSTER_FREE; - } - - switch (partition->filesysType) - { - case FS_UNKNOWN: - return CLUSTER_ERROR; - break; - - case FS_FAT12: - { - u32 nextCluster_h; - sector = partition->fat.fatStart + (((cluster * 3) / 2) / partition->bytesPerSector); - offset = ((cluster * 3) / 2) % partition->bytesPerSector; - - - _FAT_cache_readLittleEndianValue (partition->cache, &nextCluster, sector, offset, sizeof(u8)); - - offset++; - - if (offset >= partition->bytesPerSector) { - offset = 0; - sector++; - } - nextCluster_h = 0; - - _FAT_cache_readLittleEndianValue (partition->cache, &nextCluster_h, sector, offset, sizeof(u8)); - nextCluster |= (nextCluster_h << 8); - - if (cluster & 0x01) { - nextCluster = nextCluster >> 4; - } else { - nextCluster &= 0x0FFF; - } - - if (nextCluster >= 0x0FF7) - { - nextCluster = CLUSTER_EOF; - } - - break; - } - case FS_FAT16: - sector = partition->fat.fatStart + ((cluster << 1) / partition->bytesPerSector); - offset = (cluster % (partition->bytesPerSector >> 1)) << 1; - - _FAT_cache_readLittleEndianValue (partition->cache, &nextCluster, sector, offset, sizeof(u16)); - - if (nextCluster >= 0xFFF7) { - nextCluster = CLUSTER_EOF; - } - break; - - case FS_FAT32: - sector = partition->fat.fatStart + ((cluster << 2) / partition->bytesPerSector); - offset = (cluster % (partition->bytesPerSector >> 2)) << 2; - - _FAT_cache_readLittleEndianValue (partition->cache, &nextCluster, sector, offset, sizeof(u32)); - - if (nextCluster >= 0x0FFFFFF7) { - nextCluster = CLUSTER_EOF; - } - break; - - default: - return CLUSTER_ERROR; - break; - } - - return nextCluster; -} - -/* -writes value into the correct offset within a partition's FAT, based -on the cluster number. -*/ -static bool _FAT_fat_writeFatEntry (PARTITION* partition, uint32_t cluster, uint32_t value) { - sec_t sector; - int offset; - uint32_t oldValue; - - if ((cluster < CLUSTER_FIRST) || (cluster > partition->fat.lastCluster /* This will catch CLUSTER_ERROR */)) - { - return false; - } - - switch (partition->filesysType) - { - case FS_UNKNOWN: - return false; - break; - - case FS_FAT12: - sector = partition->fat.fatStart + (((cluster * 3) / 2) / partition->bytesPerSector); - offset = ((cluster * 3) / 2) % partition->bytesPerSector; - - if (cluster & 0x01) { - - _FAT_cache_readLittleEndianValue (partition->cache, &oldValue, sector, offset, sizeof(u8)); - - value = (value << 4) | (oldValue & 0x0F); - - _FAT_cache_writeLittleEndianValue (partition->cache, value & 0xFF, sector, offset, sizeof(u8)); - - offset++; - if (offset >= partition->bytesPerSector) { - offset = 0; - sector++; - } - - _FAT_cache_writeLittleEndianValue (partition->cache, (value >> 8) & 0xFF, sector, offset, sizeof(u8)); - - } else { - - _FAT_cache_writeLittleEndianValue (partition->cache, value, sector, offset, sizeof(u8)); - - offset++; - if (offset >= partition->bytesPerSector) { - offset = 0; - sector++; - } - - _FAT_cache_readLittleEndianValue (partition->cache, &oldValue, sector, offset, sizeof(u8)); - - value = ((value >> 8) & 0x0F) | (oldValue & 0xF0); - - _FAT_cache_writeLittleEndianValue (partition->cache, value, sector, offset, sizeof(u8)); - } - - break; - - case FS_FAT16: - sector = partition->fat.fatStart + ((cluster << 1) / partition->bytesPerSector); - offset = (cluster % (partition->bytesPerSector >> 1)) << 1; - - _FAT_cache_writeLittleEndianValue (partition->cache, value, sector, offset, sizeof(u16)); - - break; - - case FS_FAT32: - sector = partition->fat.fatStart + ((cluster << 2) / partition->bytesPerSector); - offset = (cluster % (partition->bytesPerSector >> 2)) << 2; - - _FAT_cache_writeLittleEndianValue (partition->cache, value, sector, offset, sizeof(u32)); - - break; - - default: - return false; - break; - } - - return true; -} - -/*----------------------------------------------------------------- -gets the first available free cluster, sets it -to end of file, links the input cluster to it then returns the -cluster number -If an error occurs, return CLUSTER_ERROR ------------------------------------------------------------------*/ -uint32_t _FAT_fat_linkFreeCluster(PARTITION* partition, uint32_t cluster) { - uint32_t firstFree; - uint32_t curLink; - uint32_t lastCluster; - bool loopedAroundFAT = false; - - lastCluster = partition->fat.lastCluster; - - if (cluster > lastCluster) { - return CLUSTER_ERROR; - } - - // Check if the cluster already has a link, and return it if so - curLink = _FAT_fat_nextCluster(partition, cluster); - if ((curLink >= CLUSTER_FIRST) && (curLink <= lastCluster)) { - return curLink; // Return the current link - don't allocate a new one - } - - // Get a free cluster - firstFree = partition->fat.firstFree; - // Start at first valid cluster - if (firstFree < CLUSTER_FIRST) { - firstFree = CLUSTER_FIRST; - } - - // Search until a free cluster is found - while (_FAT_fat_nextCluster(partition, firstFree) != CLUSTER_FREE) { - firstFree++; - if (firstFree > lastCluster) { - if (loopedAroundFAT) { - // If couldn't get a free cluster then return an error - partition->fat.firstFree = firstFree; - return CLUSTER_ERROR; - } else { - // Try looping back to the beginning of the FAT - // This was suggested by loopy - firstFree = CLUSTER_FIRST; - loopedAroundFAT = true; - } - } - } - partition->fat.firstFree = firstFree; - if(partition->fat.numberFreeCluster) - partition->fat.numberFreeCluster--; - partition->fat.numberLastAllocCluster = firstFree; - - if ((cluster >= CLUSTER_FIRST) && (cluster <= lastCluster)) - { - // Update the linked from FAT entry - _FAT_fat_writeFatEntry (partition, cluster, firstFree); - } - // Create the linked to FAT entry - _FAT_fat_writeFatEntry (partition, firstFree, CLUSTER_EOF); - - return firstFree; -} - -/*----------------------------------------------------------------- -gets the first available free cluster, sets it -to end of file, links the input cluster to it, clears the new -cluster to 0 valued bytes, then returns the cluster number -If an error occurs, return CLUSTER_ERROR ------------------------------------------------------------------*/ -uint32_t _FAT_fat_linkFreeClusterCleared (PARTITION* partition, uint32_t cluster) { - uint32_t newCluster; - uint32_t i; - uint8_t *emptySector; - - // Link the cluster - newCluster = _FAT_fat_linkFreeCluster(partition, cluster); - - if (newCluster == CLUSTER_FREE || newCluster == CLUSTER_ERROR) { - return CLUSTER_ERROR; - } - - emptySector = (uint8_t*) _FAT_mem_allocate(partition->bytesPerSector); - - // Clear all the sectors within the cluster - memset (emptySector, 0, partition->bytesPerSector); - for (i = 0; i < partition->sectorsPerCluster; i++) { - _FAT_cache_writeSectors (partition->cache, - _FAT_fat_clusterToSector (partition, newCluster) + i, - 1, emptySector); - } - - _FAT_mem_free(emptySector); - - return newCluster; -} - - -/*----------------------------------------------------------------- -_FAT_fat_clearLinks -frees any cluster used by a file ------------------------------------------------------------------*/ -bool _FAT_fat_clearLinks (PARTITION* partition, uint32_t cluster) { - uint32_t nextCluster; - - if ((cluster < CLUSTER_FIRST) || (cluster > partition->fat.lastCluster /* This will catch CLUSTER_ERROR */)) - return false; - - // If this clears up more space in the FAT before the current free pointer, move it backwards - if (cluster < partition->fat.firstFree) { - partition->fat.firstFree = cluster; - } - - while ((cluster != CLUSTER_EOF) && (cluster != CLUSTER_FREE) && (cluster != CLUSTER_ERROR)) { - // Store next cluster before erasing the link - nextCluster = _FAT_fat_nextCluster (partition, cluster); - - // Erase the link - _FAT_fat_writeFatEntry (partition, cluster, CLUSTER_FREE); - - if(partition->fat.numberFreeCluster < (partition->numberOfSectors/partition->sectorsPerCluster)) - partition->fat.numberFreeCluster++; - // Move onto next cluster - cluster = nextCluster; - } - - return true; -} - -/*----------------------------------------------------------------- -_FAT_fat_trimChain -Drop all clusters past the chainLength. -If chainLength is 0, all clusters are dropped. -If chainLength is 1, the first cluster is kept and the rest are -dropped, and so on. -Return the last cluster left in the chain. ------------------------------------------------------------------*/ -uint32_t _FAT_fat_trimChain (PARTITION* partition, uint32_t startCluster, unsigned int chainLength) { - uint32_t nextCluster; - - if (chainLength == 0) { - // Drop the entire chain - _FAT_fat_clearLinks (partition, startCluster); - return CLUSTER_FREE; - } else { - // Find the last cluster in the chain, and the one after it - chainLength--; - nextCluster = _FAT_fat_nextCluster (partition, startCluster); - while ((chainLength > 0) && (nextCluster != CLUSTER_FREE) && (nextCluster != CLUSTER_EOF)) { - chainLength--; - startCluster = nextCluster; - nextCluster = _FAT_fat_nextCluster (partition, startCluster); - } - - // Drop all clusters after the last in the chain - if (nextCluster != CLUSTER_FREE && nextCluster != CLUSTER_EOF) { - _FAT_fat_clearLinks (partition, nextCluster); - } - - // Mark the last cluster in the chain as the end of the file - _FAT_fat_writeFatEntry (partition, startCluster, CLUSTER_EOF); - - return startCluster; - } -} - -/*----------------------------------------------------------------- -_FAT_fat_lastCluster -Trace the cluster links until the last one is found ------------------------------------------------------------------*/ -uint32_t _FAT_fat_lastCluster (PARTITION* partition, uint32_t cluster) { - while ((_FAT_fat_nextCluster(partition, cluster) != CLUSTER_FREE) && (_FAT_fat_nextCluster(partition, cluster) != CLUSTER_EOF)) { - cluster = _FAT_fat_nextCluster(partition, cluster); - } - return cluster; -} - -/*----------------------------------------------------------------- -_FAT_fat_freeClusterCount -Return the number of free clusters available ------------------------------------------------------------------*/ -unsigned int _FAT_fat_freeClusterCount (PARTITION* partition) { - unsigned int count = 0; - uint32_t curCluster; - - for (curCluster = CLUSTER_FIRST; curCluster <= partition->fat.lastCluster; curCluster++) { - if (_FAT_fat_nextCluster(partition, curCluster) == CLUSTER_FREE) { - count++; - } - } - - return count; -} - diff --git a/cube/libfat-frag/src/source/file_allocation_table.h b/cube/libfat-frag/src/source/file_allocation_table.h deleted file mode 100644 index d9c43614..00000000 --- a/cube/libfat-frag/src/source/file_allocation_table.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - file_allocation_table.h - Reading, writing and manipulation of the FAT structure on - a FAT partition - - Copyright (c) 2006 Michael "Chishm" Chisholm - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef _FAT_H -#define _FAT_H - -#include "common.h" -#include "partition.h" - -#define CLUSTER_EOF_16 0xFFFF -#define CLUSTER_EOF 0x0FFFFFFF -#define CLUSTER_FREE 0x00000000 -#define CLUSTER_ROOT 0x00000000 -#define CLUSTER_FIRST 0x00000002 -#define CLUSTER_ERROR 0xFFFFFFFF - -#define CLUSTERS_PER_FAT12 4085 -#define CLUSTERS_PER_FAT16 65525 - - -uint32_t _FAT_fat_nextCluster(PARTITION* partition, uint32_t cluster); - -uint32_t _FAT_fat_linkFreeCluster(PARTITION* partition, uint32_t cluster); -uint32_t _FAT_fat_linkFreeClusterCleared (PARTITION* partition, uint32_t cluster); - -bool _FAT_fat_clearLinks (PARTITION* partition, uint32_t cluster); - -uint32_t _FAT_fat_trimChain (PARTITION* partition, uint32_t startCluster, unsigned int chainLength); - -uint32_t _FAT_fat_lastCluster (PARTITION* partition, uint32_t cluster); - -unsigned int _FAT_fat_freeClusterCount (PARTITION* partition); - -static inline sec_t _FAT_fat_clusterToSector (PARTITION* partition, uint32_t cluster) { - return (cluster >= CLUSTER_FIRST) ? - ((cluster - CLUSTER_FIRST) * (sec_t)partition->sectorsPerCluster) + partition->dataStart : - partition->rootDirStart; -} - -static inline bool _FAT_fat_isValidCluster (PARTITION* partition, uint32_t cluster) { - return (cluster >= CLUSTER_FIRST) && (cluster <= partition->fat.lastCluster /* This will catch CLUSTER_ERROR */); -} - -#endif // _FAT_H diff --git a/cube/libfat-frag/src/source/filetime.c b/cube/libfat-frag/src/source/filetime.c deleted file mode 100644 index d297bf64..00000000 --- a/cube/libfat-frag/src/source/filetime.c +++ /dev/null @@ -1,107 +0,0 @@ -/* - filetime.c - Conversion of file time and date values to various other types - - Copyright (c) 2006 Michael "Chishm" Chisholm - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include -#include "filetime.h" -#include "common.h" - -#define MAX_HOUR 23 -#define MAX_MINUTE 59 -#define MAX_SECOND 59 - -#define MAX_MONTH 11 -#define MIN_MONTH 0 -#define MAX_DAY 31 -#define MIN_DAY 1 - -uint16_t _FAT_filetime_getTimeFromRTC (void) { -#ifdef USE_RTC_TIME - struct tm timeParts; - time_t epochTime; - - if (time(&epochTime) == (time_t)-1) { - return 0; - } - localtime_r(&epochTime, &timeParts); - - // Check that the values are all in range. - // If they are not, return 0 (no timestamp) - if ((timeParts.tm_hour < 0) || (timeParts.tm_hour > MAX_HOUR)) return 0; - if ((timeParts.tm_min < 0) || (timeParts.tm_min > MAX_MINUTE)) return 0; - if ((timeParts.tm_sec < 0) || (timeParts.tm_sec > MAX_SECOND)) return 0; - - return ( - ((timeParts.tm_hour & 0x1F) << 11) | - ((timeParts.tm_min & 0x3F) << 5) | - ((timeParts.tm_sec >> 1) & 0x1F) - ); -#else - return 0; -#endif -} - - -uint16_t _FAT_filetime_getDateFromRTC (void) { -#ifdef USE_RTC_TIME - struct tm timeParts; - time_t epochTime; - - if (time(&epochTime) == (time_t)-1) { - return 0; - } - localtime_r(&epochTime, &timeParts); - - if ((timeParts.tm_mon < MIN_MONTH) || (timeParts.tm_mon > MAX_MONTH)) return 0; - if ((timeParts.tm_mday < MIN_DAY) || (timeParts.tm_mday > MAX_DAY)) return 0; - - return ( - (((timeParts.tm_year - 80) & 0x7F) <<9) | // Adjust for MS-FAT base year (1980 vs 1900 for tm_year) - (((timeParts.tm_mon + 1) & 0xF) << 5) | - (timeParts.tm_mday & 0x1F) - ); -#else - return 0; -#endif -} - -time_t _FAT_filetime_to_time_t (uint16_t t, uint16_t d) { - struct tm timeParts; - - timeParts.tm_hour = t >> 11; - timeParts.tm_min = (t >> 5) & 0x3F; - timeParts.tm_sec = (t & 0x1F) << 1; - - timeParts.tm_mday = d & 0x1F; - timeParts.tm_mon = ((d >> 5) & 0x0F) - 1; - timeParts.tm_year = (d >> 9) + 80; - - timeParts.tm_isdst = 0; - - return mktime(&timeParts); -} diff --git a/cube/libfat-frag/src/source/filetime.h b/cube/libfat-frag/src/source/filetime.h deleted file mode 100644 index 3bfd8ed8..00000000 --- a/cube/libfat-frag/src/source/filetime.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - filetime.h - Conversion of file time and date values to various other types - - Copyright (c) 2006 Michael "Chishm" Chisholm - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef _FILETIME_H -#define _FILETIME_H - -#include "common.h" -#include - -uint16_t _FAT_filetime_getTimeFromRTC (void); -uint16_t _FAT_filetime_getDateFromRTC (void); - -time_t _FAT_filetime_to_time_t (uint16_t t, uint16_t d); - - -#endif // _FILETIME_H diff --git a/cube/libfat-frag/src/source/libfat.c b/cube/libfat-frag/src/source/libfat.c deleted file mode 100644 index aabb3ad6..00000000 --- a/cube/libfat-frag/src/source/libfat.c +++ /dev/null @@ -1,251 +0,0 @@ -/* - libfat.c - Simple functionality for startup, mounting and unmounting of FAT-based devices. - - Copyright (c) 2006 Michael "Chishm" Chisholm - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include -#include -#include -#include -#include - -#include "common.h" -#include "partition.h" -#include "fatfile.h" -#include "fatdir.h" -#include "lock.h" -#include "mem_allocate.h" -#include "disc.h" - -static const devoptab_t dotab_fat = { - "fat", - sizeof (FILE_STRUCT), - _FAT_open_r, - _FAT_close_r, - _FAT_write_r, - _FAT_read_r, - _FAT_seek_r, - _FAT_fstat_r, - _FAT_stat_r, - _FAT_link_r, - _FAT_unlink_r, - _FAT_chdir_r, - _FAT_rename_r, - _FAT_mkdir_r, - sizeof (DIR_STATE_STRUCT), - _FAT_diropen_r, - _FAT_dirreset_r, - _FAT_dirnext_r, - _FAT_dirclose_r, - _FAT_statvfs_r, - _FAT_ftruncate_r, - _FAT_fsync_r, - NULL, /* Device data */ - NULL, - NULL -}; - -bool fatMount (const char* name, const DISC_INTERFACE* interface, sec_t startSector, uint32_t cacheSize, uint32_t SectorsPerPage) { - PARTITION* partition; - devoptab_t* devops; - char* nameCopy; - - if(!name || strlen(name) > 8 || !interface) - return false; - - if(!interface->startup()) - return false; - - if(!interface->isInserted()) - return false; - - char devname[10]; - strcpy(devname, name); - strcat(devname, ":"); - if(FindDevice(devname) >= 0) - return true; - - devops = _FAT_mem_allocate (sizeof(devoptab_t) + strlen(name) + 1); - if (!devops) { - return false; - } - // Use the space allocated at the end of the devoptab struct for storing the name - nameCopy = (char*)(devops+1); - - // Initialize the file system - partition = _FAT_partition_constructor (interface, cacheSize, SectorsPerPage, startSector); - if (!partition) { - _FAT_mem_free (devops); - return false; - } - - // Add an entry for this device to the devoptab table - memcpy (devops, &dotab_fat, sizeof(dotab_fat)); - strcpy (nameCopy, name); - devops->name = nameCopy; - devops->deviceData = partition; - - AddDevice (devops); - - return true; -} - -bool fatMountSimple (const char* name, const DISC_INTERFACE* interface) { - return fatMount (name, interface, 0, DEFAULT_CACHE_PAGES, DEFAULT_SECTORS_PAGE); -} - -void fatUnmount (const char* name) { - devoptab_t *devops; - PARTITION* partition; - - if(!name) - return; - - devops = (devoptab_t*)GetDeviceOpTab (name); - if (!devops) { - return; - } - - // Perform a quick check to make sure we're dealing with a libfat controlled device - if (devops->open_r != dotab_fat.open_r) { - return; - } - - if (RemoveDevice (name) == -1) { - return; - } - - partition = (PARTITION*)devops->deviceData; - _FAT_partition_destructor (partition); - _FAT_mem_free (devops); -} - -bool fatInit (uint32_t cacheSize, bool setAsDefaultDevice) { - int i; - int defaultDevice = -1; - const DISC_INTERFACE *disc; - - for (i = 0; - _FAT_disc_interfaces[i].name != NULL && _FAT_disc_interfaces[i].getInterface != NULL; - i++) - { - disc = _FAT_disc_interfaces[i].getInterface(); - if (fatMount (_FAT_disc_interfaces[i].name, disc, 0, cacheSize, DEFAULT_SECTORS_PAGE)) { - // The first device to successfully mount is set as the default - if (defaultDevice < 0) { - defaultDevice = i; - } - } - } - - if (defaultDevice < 0) { - // None of our devices mounted - return false; - } - - if (setAsDefaultDevice) { - char filePath[MAXPATHLEN * 2]; - strcpy (filePath, _FAT_disc_interfaces[defaultDevice].name); - strcat (filePath, ":/"); -#ifdef ARGV_MAGIC - if ( __system_argv->argvMagic == ARGV_MAGIC && __system_argv->argc >= 1 && strrchr( __system_argv->argv[0], '/' )!=NULL ) { - // Check the app's path against each of our mounted devices, to see - // if we can support it. If so, change to that path. - for (i = 0; - _FAT_disc_interfaces[i].name != NULL && _FAT_disc_interfaces[i].getInterface != NULL; - i++) - { - if ( !strncasecmp( __system_argv->argv[0], _FAT_disc_interfaces[i].name, - strlen(_FAT_disc_interfaces[i].name))) - { - char *lastSlash; - strcpy(filePath, __system_argv->argv[0]); - lastSlash = strrchr( filePath, '/' ); - - if ( NULL != lastSlash) { - if ( *(lastSlash - 1) == ':') lastSlash++; - *lastSlash = 0; - } - } - } - } -#endif - chdir (filePath); - } - - return true; -} - -bool fatInitDefault (void) { - return fatInit (DEFAULT_CACHE_PAGES, true); -} - -void fatGetVolumeLabel (const char* name, char *label) { - devoptab_t *devops; - PARTITION* partition; - char *buf; - int namelen,i; - - if(!name || !label) - return; - - namelen = strlen(name); - buf=(char*)_FAT_mem_allocate(sizeof(char)*namelen+2); - strcpy(buf,name); - - if (name[namelen-1] == '/') { - buf[namelen-1]='\0'; - namelen--; - } - - if (name[namelen-1] != ':') { - buf[namelen]=':'; - buf[namelen+1]='\0'; - } - - devops = (devoptab_t*)GetDeviceOpTab(buf); - - for(i=0;buf[i]!='\0' && buf[i]!=':';i++); - if (!devops || strncasecmp(buf,devops->name,i)) { - _FAT_mem_free(buf); - return; - } - - _FAT_mem_free(buf); - - // Perform a quick check to make sure we're dealing with a libfat controlled device - if (devops->open_r != dotab_fat.open_r) { - return; - } - - partition = (PARTITION*)devops->deviceData; - - if(!_FAT_directory_getVolumeLabel(partition, label)) { - strncpy(label,partition->label,11); - label[11]='\0'; - } - if(!strncmp(label, "NO NAME", 7)) label[0]='\0'; -} diff --git a/cube/libfat-frag/src/source/lock.c b/cube/libfat-frag/src/source/lock.c deleted file mode 100644 index 59c3444c..00000000 --- a/cube/libfat-frag/src/source/lock.c +++ /dev/null @@ -1,29 +0,0 @@ -#include "common.h" - -#ifndef USE_LWP_LOCK - -#ifndef mutex_t -typedef int mutex_t; -#endif - -void __attribute__ ((weak)) _FAT_lock_init(mutex_t *mutex) -{ - return; -} - -void __attribute__ ((weak)) _FAT_lock_deinit(mutex_t *mutex) -{ - return; -} - -void __attribute__ ((weak)) _FAT_lock(mutex_t *mutex) -{ - return; -} - -void __attribute__ ((weak)) _FAT_unlock(mutex_t *mutex) -{ - return; -} - -#endif // USE_LWP_LOCK diff --git a/cube/libfat-frag/src/source/lock.h b/cube/libfat-frag/src/source/lock.h deleted file mode 100644 index de5723a9..00000000 --- a/cube/libfat-frag/src/source/lock.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - lock.h - - Copyright (c) 2008 Sven Peter - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ - -#ifndef _LOCK_H -#define _LOCK_H - -#include "common.h" - -#ifdef USE_LWP_LOCK - -static inline void _FAT_lock_init(mutex_t *mutex) -{ - LWP_MutexInit(mutex, false); -} - -static inline void _FAT_lock_deinit(mutex_t *mutex) -{ - LWP_MutexDestroy(*mutex); -} - -static inline void _FAT_lock(mutex_t *mutex) -{ - LWP_MutexLock(*mutex); -} - -static inline void _FAT_unlock(mutex_t *mutex) -{ - LWP_MutexUnlock(*mutex); -} - -#else - -// We still need a blank lock type -#ifndef mutex_t -typedef int mutex_t; -#endif - -void _FAT_lock_init(mutex_t *mutex); -void _FAT_lock_deinit(mutex_t *mutex); -void _FAT_lock(mutex_t *mutex); -void _FAT_unlock(mutex_t *mutex); - -#endif // USE_LWP_LOCK - - -#endif // _LOCK_H - diff --git a/cube/libfat-frag/src/source/mem_allocate.h b/cube/libfat-frag/src/source/mem_allocate.h deleted file mode 100644 index 3308807a..00000000 --- a/cube/libfat-frag/src/source/mem_allocate.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - mem_allocate.h - Memory allocation and destruction calls - Replace these calls with custom allocators if - malloc is unavailable - - Copyright (c) 2006 Michael "Chishm" Chisholm - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef _MEM_ALLOCATE_H -#define _MEM_ALLOCATE_H - -#include - -static inline void* _FAT_mem_allocate (size_t size) { - return malloc (size); -} - -static inline void* _FAT_mem_align (size_t size) { -#ifdef __wii__ - return memalign (32, size); -#else - return malloc (size); -#endif -} - -static inline void _FAT_mem_free (void* mem) { - free (mem); -} - -#endif // _MEM_ALLOCATE_H diff --git a/cube/libfat-frag/src/source/partition.c b/cube/libfat-frag/src/source/partition.c deleted file mode 100644 index 108776a6..00000000 --- a/cube/libfat-frag/src/source/partition.c +++ /dev/null @@ -1,441 +0,0 @@ -/* - partition.c - Functions for mounting and dismounting partitions - on various block devices. - - Copyright (c) 2006 Michael "Chishm" Chisholm - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include "partition.h" -#include "bit_ops.h" -#include "file_allocation_table.h" -#include "directory.h" -#include "mem_allocate.h" -#include "fatfile.h" - -#include -#include -#include - -/* -Data offsets -*/ - -// BIOS Parameter Block offsets -enum BPB { - BPB_jmpBoot = 0x00, - BPB_OEMName = 0x03, - // BIOS Parameter Block - BPB_bytesPerSector = 0x0B, - BPB_sectorsPerCluster = 0x0D, - BPB_reservedSectors = 0x0E, - BPB_numFATs = 0x10, - BPB_rootEntries = 0x11, - BPB_numSectorsSmall = 0x13, - BPB_mediaDesc = 0x15, - BPB_sectorsPerFAT = 0x16, - BPB_sectorsPerTrk = 0x18, - BPB_numHeads = 0x1A, - BPB_numHiddenSectors = 0x1C, - BPB_numSectors = 0x20, - // Ext BIOS Parameter Block for FAT16 - BPB_FAT16_driveNumber = 0x24, - BPB_FAT16_reserved1 = 0x25, - BPB_FAT16_extBootSig = 0x26, - BPB_FAT16_volumeID = 0x27, - BPB_FAT16_volumeLabel = 0x2B, - BPB_FAT16_fileSysType = 0x36, - // Bootcode - BPB_FAT16_bootCode = 0x3E, - // FAT32 extended block - BPB_FAT32_sectorsPerFAT32 = 0x24, - BPB_FAT32_extFlags = 0x28, - BPB_FAT32_fsVer = 0x2A, - BPB_FAT32_rootClus = 0x2C, - BPB_FAT32_fsInfo = 0x30, - BPB_FAT32_bkBootSec = 0x32, - // Ext BIOS Parameter Block for FAT32 - BPB_FAT32_driveNumber = 0x40, - BPB_FAT32_reserved1 = 0x41, - BPB_FAT32_extBootSig = 0x42, - BPB_FAT32_volumeID = 0x43, - BPB_FAT32_volumeLabel = 0x47, - BPB_FAT32_fileSysType = 0x52, - // Bootcode - BPB_FAT32_bootCode = 0x5A, - BPB_bootSig_55 = 0x1FE, - BPB_bootSig_AA = 0x1FF -}; - -// File system information block offsets -enum FSIB -{ - FSIB_SIG1 = 0x00, - FSIB_SIG2 = 0x1e4, - FSIB_numberOfFreeCluster = 0x1e8, - FSIB_numberLastAllocCluster = 0x1ec, - FSIB_bootSig_55 = 0x1FE, - FSIB_bootSig_AA = 0x1FF -}; - -static const char FAT_SIG[3] = {'F', 'A', 'T'}; -static const char FS_INFO_SIG1[4] = {'R', 'R', 'a', 'A'}; -static const char FS_INFO_SIG2[4] = {'r', 'r', 'A', 'a'}; - -sec_t FindFirstValidPartition_buf(const DISC_INTERFACE* disc, uint8_t *sectorBuffer) -{ - uint8_t part_table[16*4]; - uint8_t *ptr; - int i; - - // Read first sector of disc - if (!_FAT_disc_readSectors (disc, 0, 1, sectorBuffer)) { - return 0; - } - - memcpy(part_table,sectorBuffer+0x1BE,16*4); - ptr = part_table; - - for(i=0;i<4;i++,ptr+=16) { - sec_t part_lba = u8array_to_u32(ptr, 0x8); - - if (!memcmp(sectorBuffer + BPB_FAT16_fileSysType, FAT_SIG, sizeof(FAT_SIG)) || - !memcmp(sectorBuffer + BPB_FAT32_fileSysType, FAT_SIG, sizeof(FAT_SIG))) { - return part_lba; - } - - if(ptr[4]==0) continue; - - if(ptr[4]==0x0F) { - sec_t part_lba2=part_lba; - sec_t next_lba2=0; - int n; - - for(n=0;n<8;n++) // max 8 logic partitions - { - if(!_FAT_disc_readSectors (disc, part_lba+next_lba2, 1, sectorBuffer)) return 0; - - part_lba2 = part_lba + next_lba2 + u8array_to_u32(sectorBuffer, 0x1C6) ; - next_lba2 = u8array_to_u32(sectorBuffer, 0x1D6); - - if(!_FAT_disc_readSectors (disc, part_lba2, 1, sectorBuffer)) return 0; - - if (!memcmp(sectorBuffer + BPB_FAT16_fileSysType, FAT_SIG, sizeof(FAT_SIG)) || - !memcmp(sectorBuffer + BPB_FAT32_fileSysType, FAT_SIG, sizeof(FAT_SIG))) - { - return part_lba2; - } - - if(next_lba2==0) break; - } - } else { - if(!_FAT_disc_readSectors (disc, part_lba, 1, sectorBuffer)) return 0; - if (!memcmp(sectorBuffer + BPB_FAT16_fileSysType, FAT_SIG, sizeof(FAT_SIG)) || - !memcmp(sectorBuffer + BPB_FAT32_fileSysType, FAT_SIG, sizeof(FAT_SIG))) { - return part_lba; - } - } - } - return 0; -} - -sec_t FindFirstValidPartition(const DISC_INTERFACE* disc) -{ - uint8_t *sectorBuffer = (uint8_t*) _FAT_mem_align(MAX_SECTOR_SIZE); - if (!sectorBuffer) return 0; - sec_t ret = FindFirstValidPartition_buf(disc, sectorBuffer); - _FAT_mem_free(sectorBuffer); - return ret; -} - - -PARTITION* _FAT_partition_constructor_buf (const DISC_INTERFACE* disc, uint32_t cacheSize, uint32_t sectorsPerPage, sec_t startSector, uint8_t *sectorBuffer) -{ - PARTITION* partition; - - // Read first sector of disc - if (!_FAT_disc_readSectors (disc, startSector, 1, sectorBuffer)) { - return NULL; - } - - // Make sure it is a valid MBR or boot sector - if ( (sectorBuffer[BPB_bootSig_55] != 0x55) || (sectorBuffer[BPB_bootSig_AA] != 0xAA)) { - return NULL; - } - - if (startSector != 0) { - // We're told where to start the partition, so just accept it - } else if (!memcmp(sectorBuffer + BPB_FAT16_fileSysType, FAT_SIG, sizeof(FAT_SIG))) { - // Check if there is a FAT string, which indicates this is a boot sector - startSector = 0; - } else if (!memcmp(sectorBuffer + BPB_FAT32_fileSysType, FAT_SIG, sizeof(FAT_SIG))) { - // Check for FAT32 - startSector = 0; - } else { - startSector = FindFirstValidPartition_buf(disc, sectorBuffer); - if (!_FAT_disc_readSectors (disc, startSector, 1, sectorBuffer)) { - return NULL; - } - } - - // Now verify that this is indeed a FAT partition - if (memcmp(sectorBuffer + BPB_FAT16_fileSysType, FAT_SIG, sizeof(FAT_SIG)) && - memcmp(sectorBuffer + BPB_FAT32_fileSysType, FAT_SIG, sizeof(FAT_SIG))) - { - return NULL; - } - - partition = (PARTITION*) _FAT_mem_allocate (sizeof(PARTITION)); - if (partition == NULL) { - return NULL; - } - - // Init the partition lock - _FAT_lock_init(&partition->lock); - - if (!memcmp(sectorBuffer + BPB_FAT16_fileSysType, FAT_SIG, sizeof(FAT_SIG))) - strncpy(partition->label, (char*)(sectorBuffer + BPB_FAT16_volumeLabel), 11); - else - strncpy(partition->label, (char*)(sectorBuffer + BPB_FAT32_volumeLabel), 11); - partition->label[11] = '\0'; - - // Set partition's disc interface - partition->disc = disc; - - // Store required information about the file system - partition->fat.sectorsPerFat = u8array_to_u16(sectorBuffer, BPB_sectorsPerFAT); - if (partition->fat.sectorsPerFat == 0) { - partition->fat.sectorsPerFat = u8array_to_u32( sectorBuffer, BPB_FAT32_sectorsPerFAT32); - } - - partition->numberOfSectors = u8array_to_u16( sectorBuffer, BPB_numSectorsSmall); - if (partition->numberOfSectors == 0) { - partition->numberOfSectors = u8array_to_u32( sectorBuffer, BPB_numSectors); - } - - partition->bytesPerSector = u8array_to_u16(sectorBuffer, BPB_bytesPerSector); - if(partition->bytesPerSector < MIN_SECTOR_SIZE || partition->bytesPerSector > MAX_SECTOR_SIZE) { - // Unsupported sector size - _FAT_mem_free(partition); - return NULL; - } - - partition->sectorsPerCluster = sectorBuffer[BPB_sectorsPerCluster]; - partition->bytesPerCluster = partition->bytesPerSector * partition->sectorsPerCluster; - partition->fat.fatStart = startSector + u8array_to_u16(sectorBuffer, BPB_reservedSectors); - - partition->rootDirStart = partition->fat.fatStart + (sectorBuffer[BPB_numFATs] * partition->fat.sectorsPerFat); - partition->dataStart = partition->rootDirStart + - (( u8array_to_u16(sectorBuffer, BPB_rootEntries) * DIR_ENTRY_DATA_SIZE) / partition->bytesPerSector); - - partition->totalSize = ((uint64_t)partition->numberOfSectors - (partition->dataStart - startSector)) * (uint64_t)partition->bytesPerSector; - - //FS info sector - partition->fsInfoSector = startSector + (u8array_to_u16(sectorBuffer, BPB_FAT32_fsInfo) ? u8array_to_u16(sectorBuffer, BPB_FAT32_fsInfo) : 1); - - // Store info about FAT - uint32_t clusterCount = (partition->numberOfSectors - (uint32_t)(partition->dataStart - startSector)) / partition->sectorsPerCluster; - partition->fat.lastCluster = clusterCount + CLUSTER_FIRST - 1; - partition->fat.firstFree = CLUSTER_FIRST; - partition->fat.numberFreeCluster = 0; - partition->fat.numberLastAllocCluster = 0; - - if (clusterCount < CLUSTERS_PER_FAT12) { - partition->filesysType = FS_FAT12; // FAT12 volume - } else if (clusterCount < CLUSTERS_PER_FAT16) { - partition->filesysType = FS_FAT16; // FAT16 volume - } else { - partition->filesysType = FS_FAT32; // FAT32 volume - } - - if (partition->filesysType != FS_FAT32) { - partition->rootDirCluster = FAT16_ROOT_DIR_CLUSTER; - } else { - // Set up for the FAT32 way - partition->rootDirCluster = u8array_to_u32(sectorBuffer, BPB_FAT32_rootClus); - // Check if FAT mirroring is enabled - if (!(sectorBuffer[BPB_FAT32_extFlags] & 0x80)) { - // Use the active FAT - partition->fat.fatStart = partition->fat.fatStart + ( partition->fat.sectorsPerFat * (sectorBuffer[BPB_FAT32_extFlags] & 0x0F)); - } - } - - // Create a cache to use - partition->cache = _FAT_cache_constructor (cacheSize, sectorsPerPage, partition->disc, startSector+partition->numberOfSectors, partition->bytesPerSector); - - // Set current directory to the root - partition->cwdCluster = partition->rootDirCluster; - - // Check if this disc is writable, and set the readOnly property appropriately - partition->readOnly = !(_FAT_disc_features(disc) & FEATURE_MEDIUM_CANWRITE); - - // There are currently no open files on this partition - partition->openFileCount = 0; - partition->firstOpenFile = NULL; - - _FAT_partition_readFSinfo(partition); - - return partition; -} - -PARTITION* _FAT_partition_constructor (const DISC_INTERFACE* disc, uint32_t cacheSize, uint32_t sectorsPerPage, sec_t startSector) -{ - uint8_t *sectorBuffer = (uint8_t*) _FAT_mem_align(MAX_SECTOR_SIZE); - if (!sectorBuffer) return NULL; - PARTITION *ret = _FAT_partition_constructor_buf(disc, cacheSize, - sectorsPerPage, startSector, sectorBuffer); - _FAT_mem_free(sectorBuffer); - return ret; -} - - -void _FAT_partition_destructor (PARTITION* partition) { - FILE_STRUCT* nextFile; - - _FAT_lock(&partition->lock); - - // Synchronize open files - nextFile = partition->firstOpenFile; - while (nextFile) { - _FAT_syncToDisc (nextFile); - nextFile = nextFile->nextOpenFile; - } - - // Write out the fs info sector - _FAT_partition_writeFSinfo(partition); - - // Free memory used by the cache, writing it to disc at the same time - _FAT_cache_destructor (partition->cache); - - // Unlock the partition and destroy the lock - _FAT_unlock(&partition->lock); - _FAT_lock_deinit(&partition->lock); - - // Free memory used by the partition - _FAT_mem_free (partition); -} - -PARTITION* _FAT_partition_getPartitionFromPath (const char* path) { - const devoptab_t *devops; - - devops = GetDeviceOpTab (path); - - if (!devops) { - return NULL; - } - - return (PARTITION*)devops->deviceData; -} - -void _FAT_partition_createFSinfo(PARTITION * partition) -{ - if(partition->readOnly || partition->filesysType != FS_FAT32) - return; - - uint8_t *sectorBuffer = (uint8_t*) _FAT_mem_align(partition->bytesPerSector); - if (!sectorBuffer) return; - memset(sectorBuffer, 0, partition->bytesPerSector); - - int i; - for(i = 0; i < 4; ++i) - { - sectorBuffer[FSIB_SIG1+i] = FS_INFO_SIG1[i]; - sectorBuffer[FSIB_SIG2+i] = FS_INFO_SIG2[i]; - } - - partition->fat.numberFreeCluster = _FAT_fat_freeClusterCount(partition); - u32_to_u8array(sectorBuffer, FSIB_numberOfFreeCluster, partition->fat.numberFreeCluster); - u32_to_u8array(sectorBuffer, FSIB_numberLastAllocCluster, partition->fat.numberLastAllocCluster); - - sectorBuffer[FSIB_bootSig_55] = 0x55; - sectorBuffer[FSIB_bootSig_AA] = 0xAA; - - _FAT_disc_writeSectors (partition->disc, partition->fsInfoSector, 1, sectorBuffer); - - _FAT_mem_free(sectorBuffer); -} - -void _FAT_partition_readFSinfo(PARTITION * partition) -{ - if(partition->filesysType != FS_FAT32) - return; - - uint8_t *sectorBuffer = (uint8_t*) _FAT_mem_align(partition->bytesPerSector); - if (!sectorBuffer) return; - memset(sectorBuffer, 0, partition->bytesPerSector); - // Read first sector of disc - if (!_FAT_disc_readSectors (partition->disc, partition->fsInfoSector, 1, sectorBuffer)) { - _FAT_mem_free(sectorBuffer); - return; - } - - if(memcmp(sectorBuffer+FSIB_SIG1, FS_INFO_SIG1, 4) != 0 || - memcmp(sectorBuffer+FSIB_SIG2, FS_INFO_SIG2, 4) != 0 || - u8array_to_u32(sectorBuffer, FSIB_numberOfFreeCluster) == 0) - { - //sector does not yet exist, create one! - _FAT_partition_createFSinfo(partition); - } else { - partition->fat.numberFreeCluster = u8array_to_u32(sectorBuffer, FSIB_numberOfFreeCluster); - partition->fat.numberLastAllocCluster = u8array_to_u32(sectorBuffer, FSIB_numberLastAllocCluster); - } - _FAT_mem_free(sectorBuffer); -} - -void _FAT_partition_writeFSinfo(PARTITION * partition) -{ - if(partition->filesysType != FS_FAT32) - return; - - uint8_t *sectorBuffer = (uint8_t*) _FAT_mem_align(partition->bytesPerSector); - if (!sectorBuffer) return; - memset(sectorBuffer, 0, partition->bytesPerSector); - // Read first sector of disc - if (!_FAT_disc_readSectors (partition->disc, partition->fsInfoSector, 1, sectorBuffer)) { - _FAT_mem_free(sectorBuffer); - return; - } - - if(memcmp(sectorBuffer+FSIB_SIG1, FS_INFO_SIG1, 4) || memcmp(sectorBuffer+FSIB_SIG2, FS_INFO_SIG2, 4)) { - _FAT_mem_free(sectorBuffer); - return; - } - - u32_to_u8array(sectorBuffer, FSIB_numberOfFreeCluster, partition->fat.numberFreeCluster); - u32_to_u8array(sectorBuffer, FSIB_numberLastAllocCluster, partition->fat.numberLastAllocCluster); - - // Write first sector of disc - _FAT_disc_writeSectors (partition->disc, partition->fsInfoSector, 1, sectorBuffer); - _FAT_mem_free(sectorBuffer); -} - -uint32_t* _FAT_getCwdClusterPtr(const char* name) { - PARTITION *partition = _FAT_partition_getPartitionFromPath(name); - - if (!partition) { - return NULL; - } - - return &partition->cwdCluster; -} diff --git a/cube/libfat-frag/src/source/partition.h b/cube/libfat-frag/src/source/partition.h deleted file mode 100644 index ec27a0eb..00000000 --- a/cube/libfat-frag/src/source/partition.h +++ /dev/null @@ -1,107 +0,0 @@ -/* - partition.h - Functions for mounting and dismounting partitions - on various block devices. - - Copyright (c) 2006 Michael "Chishm" Chisholm - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef _PARTITION_H -#define _PARTITION_H - -#include "common.h" -#include "cache.h" -#include "lock.h" - -#define MIN_SECTOR_SIZE 512 -#define MAX_SECTOR_SIZE 4096 - -// Filesystem type -typedef enum {FS_UNKNOWN, FS_FAT12, FS_FAT16, FS_FAT32} FS_TYPE; - -typedef struct { - sec_t fatStart; - uint32_t sectorsPerFat; - uint32_t lastCluster; - uint32_t firstFree; - uint32_t numberFreeCluster; - uint32_t numberLastAllocCluster; -} FAT; - -typedef struct { - const DISC_INTERFACE* disc; - CACHE* cache; - // Info about the partition - FS_TYPE filesysType; - uint64_t totalSize; - sec_t rootDirStart; - uint32_t rootDirCluster; - uint32_t numberOfSectors; - sec_t dataStart; - uint32_t bytesPerSector; - uint32_t sectorsPerCluster; - uint32_t bytesPerCluster; - uint32_t fsInfoSector; - FAT fat; - // Values that may change after construction - uint32_t cwdCluster; // Current working directory cluster - int openFileCount; - struct _FILE_STRUCT* firstOpenFile; // The start of a linked list of files - mutex_t lock; // A lock for partition operations - bool readOnly; // If this is set, then do not try writing to the disc - char label[12]; // Volume label -} PARTITION; - -/* -Mount the supplied device and return a pointer to the struct necessary to use it -*/ -PARTITION* _FAT_partition_constructor (const DISC_INTERFACE* disc, uint32_t cacheSize, uint32_t SectorsPerPage, sec_t startSector); - -/* -Dismount the device and free all structures used. -Will also attempt to synchronise all open files to disc. -*/ -void _FAT_partition_destructor (PARTITION* partition); - -/* -Return the partition specified in a path, as taken from the devoptab. -*/ -PARTITION* _FAT_partition_getPartitionFromPath (const char* path); - -/* -Create the fs info sector. -*/ -void _FAT_partition_createFSinfo(PARTITION * partition); - -/* -Read the fs info sector data. -*/ -void _FAT_partition_readFSinfo(PARTITION * partition); - -/* -Write the fs info sector data. -*/ -void _FAT_partition_writeFSinfo(PARTITION * partition); - -#endif // _PARTITION_H diff --git a/cube/libfat-frag/src/source/tags b/cube/libfat-frag/src/source/tags deleted file mode 100644 index 73c32a46..00000000 --- a/cube/libfat-frag/src/source/tags +++ /dev/null @@ -1,346 +0,0 @@ -!_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/ -!_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/ -!_TAG_PROGRAM_AUTHOR Darren Hiebert /dhiebert@users.sourceforge.net/ -!_TAG_PROGRAM_NAME Exuberant Ctags // -!_TAG_PROGRAM_URL http://ctags.sourceforge.net /official site/ -!_TAG_PROGRAM_VERSION 5.7 // -ABOVE_UCS_RANGE directory.c 86;" d file: -ALIAS_ENTRY_LENGTH directory.h 43;" d -ATTRIB_ARCH directory.h 52;" d -ATTRIB_DIR directory.h 53;" d -ATTRIB_HID directory.h 57;" d -ATTRIB_LFN directory.h 54;" d -ATTRIB_RO directory.h 58;" d -ATTRIB_SYS directory.h 56;" d -ATTRIB_VOL directory.h 55;" d -BPB partition.c /^enum BPB {$/;" g file: -BPB_FAT16_bootCode partition.c /^ BPB_FAT16_bootCode = 0x3E,$/;" e enum:BPB file: -BPB_FAT16_driveNumber partition.c /^ BPB_FAT16_driveNumber = 0x24,$/;" e enum:BPB file: -BPB_FAT16_extBootSig partition.c /^ BPB_FAT16_extBootSig = 0x26,$/;" e enum:BPB file: -BPB_FAT16_fileSysType partition.c /^ BPB_FAT16_fileSysType = 0x36,$/;" e enum:BPB file: -BPB_FAT16_reserved1 partition.c /^ BPB_FAT16_reserved1 = 0x25,$/;" e enum:BPB file: -BPB_FAT16_volumeID partition.c /^ BPB_FAT16_volumeID = 0x27,$/;" e enum:BPB file: -BPB_FAT16_volumeLabel partition.c /^ BPB_FAT16_volumeLabel = 0x2B,$/;" e enum:BPB file: -BPB_FAT32_bkBootSec partition.c /^ BPB_FAT32_bkBootSec = 0x32,$/;" e enum:BPB file: -BPB_FAT32_bootCode partition.c /^ BPB_FAT32_bootCode = 0x5A,$/;" e enum:BPB file: -BPB_FAT32_driveNumber partition.c /^ BPB_FAT32_driveNumber = 0x40,$/;" e enum:BPB file: -BPB_FAT32_extBootSig partition.c /^ BPB_FAT32_extBootSig = 0x42,$/;" e enum:BPB file: -BPB_FAT32_extFlags partition.c /^ BPB_FAT32_extFlags = 0x28,$/;" e enum:BPB file: -BPB_FAT32_fileSysType partition.c /^ BPB_FAT32_fileSysType = 0x52,$/;" e enum:BPB file: -BPB_FAT32_fsInfo partition.c /^ BPB_FAT32_fsInfo = 0x30,$/;" e enum:BPB file: -BPB_FAT32_fsVer partition.c /^ BPB_FAT32_fsVer = 0x2A,$/;" e enum:BPB file: -BPB_FAT32_reserved1 partition.c /^ BPB_FAT32_reserved1 = 0x41,$/;" e enum:BPB file: -BPB_FAT32_rootClus partition.c /^ BPB_FAT32_rootClus = 0x2C,$/;" e enum:BPB file: -BPB_FAT32_sectorsPerFAT32 partition.c /^ BPB_FAT32_sectorsPerFAT32 = 0x24,$/;" e enum:BPB file: -BPB_FAT32_volumeID partition.c /^ BPB_FAT32_volumeID = 0x43,$/;" e enum:BPB file: -BPB_FAT32_volumeLabel partition.c /^ BPB_FAT32_volumeLabel = 0x47,$/;" e enum:BPB file: -BPB_OEMName partition.c /^ BPB_OEMName = 0x03,$/;" e enum:BPB file: -BPB_bootSig_55 partition.c /^ BPB_bootSig_55 = 0x1FE,$/;" e enum:BPB file: -BPB_bootSig_AA partition.c /^ BPB_bootSig_AA = 0x1FF$/;" e enum:BPB file: -BPB_bytesPerSector partition.c /^ BPB_bytesPerSector = 0x0B,$/;" e enum:BPB file: -BPB_jmpBoot partition.c /^ BPB_jmpBoot = 0x00,$/;" e enum:BPB file: -BPB_mediaDesc partition.c /^ BPB_mediaDesc = 0x15,$/;" e enum:BPB file: -BPB_numFATs partition.c /^ BPB_numFATs = 0x10,$/;" e enum:BPB file: -BPB_numHeads partition.c /^ BPB_numHeads = 0x1A,$/;" e enum:BPB file: -BPB_numHiddenSectors partition.c /^ BPB_numHiddenSectors = 0x1C,$/;" e enum:BPB file: -BPB_numSectors partition.c /^ BPB_numSectors = 0x20,$/;" e enum:BPB file: -BPB_numSectorsSmall partition.c /^ BPB_numSectorsSmall = 0x13,$/;" e enum:BPB file: -BPB_reservedSectors partition.c /^ BPB_reservedSectors = 0x0E,$/;" e enum:BPB file: -BPB_rootEntries partition.c /^ BPB_rootEntries = 0x11,$/;" e enum:BPB file: -BPB_sectorsPerCluster partition.c /^ BPB_sectorsPerCluster = 0x0D,$/;" e enum:BPB file: -BPB_sectorsPerFAT partition.c /^ BPB_sectorsPerFAT = 0x16,$/;" e enum:BPB file: -BPB_sectorsPerTrk partition.c /^ BPB_sectorsPerTrk = 0x18,$/;" e enum:BPB file: -BYTES_PER_READ common.h 32;" d -CACHE cache.h /^} CACHE;$/;" t typeref:struct:__anon2 -CACHE_ENTRY cache.h /^} CACHE_ENTRY;$/;" t typeref:struct:__anon1 -CACHE_FREE cache.c 47;" d file: -CACHE_PAGE_SIZE cache.h 43;" d -CLUSTERS_PER_FAT12 file_allocation_table.h 43;" d -CLUSTERS_PER_FAT16 file_allocation_table.h 44;" d -CLUSTER_EOF file_allocation_table.h 37;" d -CLUSTER_EOF_16 file_allocation_table.h 36;" d -CLUSTER_ERROR file_allocation_table.h 41;" d -CLUSTER_FIRST file_allocation_table.h 40;" d -CLUSTER_FREE file_allocation_table.h 38;" d -CLUSTER_ROOT file_allocation_table.h 39;" d -DEFAULT_CACHE_PAGES common.h 60;" d -DEFAULT_CACHE_PAGES common.h 65;" d -DEFAULT_CACHE_PAGES common.h 70;" d -DEFAULT_CACHE_PAGES common.h 74;" d -DEFAULT_SECTORS_PAGE common.h 61;" d -DEFAULT_SECTORS_PAGE common.h 66;" d -DEFAULT_SECTORS_PAGE common.h 71;" d -DEFAULT_SECTORS_PAGE common.h 75;" d -DEVICE_NAME partition.c /^const char* DEVICE_NAME = "fat";$/;" v -DIR_ENTRY directory.h /^} DIR_ENTRY;$/;" t typeref:struct:__anon5 -DIR_ENTRY_DATA_SIZE directory.h 38;" d -DIR_ENTRY_FREE directory.c 46;" d file: -DIR_ENTRY_LAST directory.c 45;" d file: -DIR_ENTRY_POSITION directory.h /^} DIR_ENTRY_POSITION;$/;" t typeref:struct:__anon4 -DIR_ENTRY_aDate directory.h /^ DIR_ENTRY_aDate = 0x12,$/;" e enum:DIR_ENTRY_offset -DIR_ENTRY_attributes directory.h /^ DIR_ENTRY_attributes = 0x0B,$/;" e enum:DIR_ENTRY_offset -DIR_ENTRY_cDate directory.h /^ DIR_ENTRY_cDate = 0x10,$/;" e enum:DIR_ENTRY_offset -DIR_ENTRY_cTime directory.h /^ DIR_ENTRY_cTime = 0x0E,$/;" e enum:DIR_ENTRY_offset -DIR_ENTRY_cTime_ms directory.h /^ DIR_ENTRY_cTime_ms = 0x0D,$/;" e enum:DIR_ENTRY_offset -DIR_ENTRY_cluster directory.h /^ DIR_ENTRY_cluster = 0x1A,$/;" e enum:DIR_ENTRY_offset -DIR_ENTRY_clusterHigh directory.h /^ DIR_ENTRY_clusterHigh = 0x14,$/;" e enum:DIR_ENTRY_offset -DIR_ENTRY_extension directory.h /^ DIR_ENTRY_extension = 0x08,$/;" e enum:DIR_ENTRY_offset -DIR_ENTRY_fileSize directory.h /^ DIR_ENTRY_fileSize = 0x1C$/;" e enum:DIR_ENTRY_offset -DIR_ENTRY_mDate directory.h /^ DIR_ENTRY_mDate = 0x18,$/;" e enum:DIR_ENTRY_offset -DIR_ENTRY_mTime directory.h /^ DIR_ENTRY_mTime = 0x16,$/;" e enum:DIR_ENTRY_offset -DIR_ENTRY_name directory.h /^ DIR_ENTRY_name = 0x00,$/;" e enum:DIR_ENTRY_offset -DIR_ENTRY_offset directory.h /^enum DIR_ENTRY_offset {$/;" g -DIR_ENTRY_reserved directory.h /^ DIR_ENTRY_reserved = 0x0C,$/;" e enum:DIR_ENTRY_offset -DIR_SEPARATOR directory.h 49;" d -DIR_STATE_STRUCT fatdir.h /^} DIR_STATE_STRUCT;$/;" t typeref:struct:__anon7 -FAT partition.h /^} FAT;$/;" t typeref:struct:__anon10 -FAT16_ROOT_DIR_CLUSTER directory.h 47;" d -FAT_SIG partition.c /^static const char FAT_SIG[3] = {'F', 'A', 'T'};$/;" v file: -FILE_MAX_SIZE fatfile.h 42;" d -FILE_POSITION fatfile.h /^} FILE_POSITION;$/;" t typeref:struct:__anon8 -FILE_STRUCT fatfile.h /^typedef struct _FILE_STRUCT FILE_STRUCT;$/;" t typeref:struct:_FILE_STRUCT -FILE_TYPE directory.h /^typedef enum {FT_DIRECTORY, FT_FILE} FILE_TYPE;$/;" t typeref:enum:__anon3 -FS_FAT12 partition.h /^typedef enum {FS_UNKNOWN, FS_FAT12, FS_FAT16, FS_FAT32} FS_TYPE;$/;" e enum:__anon9 -FS_FAT16 partition.h /^typedef enum {FS_UNKNOWN, FS_FAT12, FS_FAT16, FS_FAT32} FS_TYPE;$/;" e enum:__anon9 -FS_FAT32 partition.h /^typedef enum {FS_UNKNOWN, FS_FAT12, FS_FAT16, FS_FAT32} FS_TYPE;$/;" e enum:__anon9 -FS_TYPE partition.h /^typedef enum {FS_UNKNOWN, FS_FAT12, FS_FAT16, FS_FAT32} FS_TYPE;$/;" t typeref:enum:__anon9 -FS_UNKNOWN partition.h /^typedef enum {FS_UNKNOWN, FS_FAT12, FS_FAT16, FS_FAT32} FS_TYPE;$/;" e enum:__anon9 -FT_DIRECTORY directory.h /^typedef enum {FT_DIRECTORY, FT_FILE} FILE_TYPE;$/;" e enum:__anon3 -FT_FILE directory.h /^typedef enum {FT_DIRECTORY, FT_FILE} FILE_TYPE;$/;" e enum:__anon3 -FindFirstValidPartition partition.c /^sec_t FindFirstValidPartition(const DISC_INTERFACE* disc)$/;" f -ILLEGAL_ALIAS_CHARACTERS directory.c /^static const char ILLEGAL_ALIAS_CHARACTERS[] = "\\\\\/:;*?\\"<>|&+,=[] ";$/;" v file: -ILLEGAL_LFN_CHARACTERS directory.c /^static const char ILLEGAL_LFN_CHARACTERS[] = "\\\\\/:*?\\"<>|";$/;" v file: -INTERFACE_ID disc.h /^} INTERFACE_ID;$/;" t typeref:struct:__anon6 -LAST_LFN_POS directory.c 48;" d file: -LAST_LFN_POS_CORRECTION directory.c 49;" d file: -LFN_DEL directory.c 77;" d file: -LFN_END directory.c 76;" d file: -LFN_ENTRY_LENGTH directory.h 42;" d -LFN_offset directory.c /^enum LFN_offset {$/;" g file: -LFN_offset_char0 directory.c /^ LFN_offset_char0 = 0x01, $/;" e enum:LFN_offset file: -LFN_offset_char1 directory.c /^ LFN_offset_char1 = 0x03,$/;" e enum:LFN_offset file: -LFN_offset_char10 directory.c /^ LFN_offset_char10 = 0x18,$/;" e enum:LFN_offset file: -LFN_offset_char11 directory.c /^ LFN_offset_char11 = 0x1C,$/;" e enum:LFN_offset file: -LFN_offset_char12 directory.c /^ LFN_offset_char12 = 0x1E$/;" e enum:LFN_offset file: -LFN_offset_char2 directory.c /^ LFN_offset_char2 = 0x05,$/;" e enum:LFN_offset file: -LFN_offset_char3 directory.c /^ LFN_offset_char3 = 0x07,$/;" e enum:LFN_offset file: -LFN_offset_char4 directory.c /^ LFN_offset_char4 = 0x09,$/;" e enum:LFN_offset file: -LFN_offset_char5 directory.c /^ LFN_offset_char5 = 0x0E,$/;" e enum:LFN_offset file: -LFN_offset_char6 directory.c /^ LFN_offset_char6 = 0x10,$/;" e enum:LFN_offset file: -LFN_offset_char7 directory.c /^ LFN_offset_char7 = 0x12,$/;" e enum:LFN_offset file: -LFN_offset_char8 directory.c /^ LFN_offset_char8 = 0x14,$/;" e enum:LFN_offset file: -LFN_offset_char9 directory.c /^ LFN_offset_char9 = 0x16,$/;" e enum:LFN_offset file: -LFN_offset_checkSum directory.c /^ LFN_offset_checkSum = 0x0D, \/\/ Checksum of short file name (alias)$/;" e enum:LFN_offset file: -LFN_offset_flag directory.c /^ LFN_offset_flag = 0x0B, \/\/ Should be equal to ATTRIB_LFN$/;" e enum:LFN_offset file: -LFN_offset_ordinal directory.c /^ LFN_offset_ordinal = 0x00, \/\/ Position within LFN$/;" e enum:LFN_offset file: -LFN_offset_reserved1 directory.c /^ LFN_offset_reserved1 = 0x0C, \/\/ Always 0x00$/;" e enum:LFN_offset file: -LFN_offset_reserved2 directory.c /^ LFN_offset_reserved2 = 0x1A, \/\/ Always 0x0000$/;" e enum:LFN_offset file: -LFN_offset_table directory.c /^static const int LFN_offset_table[13]={0x01,0x03,0x05,0x07,0x09,0x0E,0x10,0x12,0x14,0x16,0x18,0x1C,0x1E}; $/;" v file: -LIMIT_SECTORS common.h 76;" d -MAX_ALIAS_EXT_LENGTH directory.h 44;" d -MAX_ALIAS_LENGTH directory.h 41;" d -MAX_ALIAS_PRI_LENGTH directory.h 45;" d -MAX_DAY filetime.c 40;" d file: -MAX_FILENAME_LENGTH directory.h 40;" d -MAX_HOUR filetime.c 34;" d file: -MAX_LFN_LENGTH directory.h 39;" d -MAX_MINUTE filetime.c 35;" d file: -MAX_MONTH filetime.c 38;" d file: -MAX_NUMERIC_TAIL directory.h 46;" d -MAX_SECOND filetime.c 36;" d file: -MIN_DAY filetime.c 41;" d file: -MIN_MONTH filetime.c 39;" d file: -NDS common.h 40;" d -PAGE_SECTORS cache.h 42;" d -PARTITION partition.h /^} PARTITION;$/;" t typeref:struct:__anon11 -USE_LWP_LOCK common.h 62;" d -USE_LWP_LOCK common.h 67;" d -USE_RTC_TIME common.h 63;" d -USE_RTC_TIME common.h 68;" d -USE_RTC_TIME common.h 72;" d -_BIT_OPS_H bit_ops.h 30;" d -_CACHE_H cache.h 37;" d -_COMMON_H common.h 30;" d -_DIRECTORY_H directory.h 31;" d -_DISC_H disc.h 30;" d -_FATDIR_H fatdir.h 33;" d -_FATFILE_H fatfile.h 33;" d -_FAT_H file_allocation_table.h 31;" d -_FAT_cache_constructor cache.c /^CACHE* _FAT_cache_constructor (unsigned int numberOfPages, unsigned int sectorsPerPage, const DISC_INTERFACE* discInterface, sec_t endOfPartition) {$/;" f -_FAT_cache_destructor cache.c /^void _FAT_cache_destructor (CACHE* cache) {$/;" f -_FAT_cache_eraseWritePartialSector cache.c /^bool _FAT_cache_eraseWritePartialSector (CACHE* cache, const void* buffer, sec_t sector, unsigned int offset, size_t size) $/;" f -_FAT_cache_findPage cache.c /^static CACHE_ENTRY* _FAT_cache_findPage(CACHE *cache, sec_t sector, sec_t count) {$/;" f file: -_FAT_cache_flush cache.c /^bool _FAT_cache_flush (CACHE* cache) {$/;" f -_FAT_cache_getPage cache.c /^static CACHE_ENTRY* _FAT_cache_getPage(CACHE *cache,sec_t sector)$/;" f file: -_FAT_cache_invalidate cache.c /^void _FAT_cache_invalidate (CACHE* cache) {$/;" f -_FAT_cache_readLittleEndianValue cache.c /^bool _FAT_cache_readLittleEndianValue (CACHE* cache, uint32_t *value, sec_t sector, unsigned int offset, int num_bytes) {$/;" f -_FAT_cache_readPartialSector cache.c /^bool _FAT_cache_readPartialSector (CACHE* cache, void* buffer, sec_t sector, unsigned int offset, size_t size) $/;" f -_FAT_cache_readSector cache.h /^static inline bool _FAT_cache_readSector (CACHE* cache, void* buffer, sec_t sector) {$/;" f -_FAT_cache_readSectors cache.c /^bool _FAT_cache_readSectors(CACHE *cache,sec_t sector,sec_t numSectors,void *buffer)$/;" f -_FAT_cache_writeLittleEndianValue cache.c /^bool _FAT_cache_writeLittleEndianValue (CACHE* cache, const uint32_t value, sec_t sector, unsigned int offset, int size) {$/;" f -_FAT_cache_writePartialSector cache.c /^bool _FAT_cache_writePartialSector (CACHE* cache, const void* buffer, sec_t sector, unsigned int offset, size_t size) $/;" f -_FAT_cache_writeSector cache.h /^static inline bool _FAT_cache_writeSector (CACHE* cache, const void* buffer, sec_t sector) {$/;" f -_FAT_cache_writeSectors cache.c /^bool _FAT_cache_writeSectors (CACHE* cache, sec_t sector, sec_t numSectors, const void* buffer) $/;" f -_FAT_chdir_r fatdir.c /^int _FAT_chdir_r (struct _reent *r, const char *path) {$/;" f -_FAT_check_position_for_next_cluster fatfile.c /^static bool _FAT_check_position_for_next_cluster(struct _reent *r,$/;" f file: -_FAT_close_r fatfile.c /^int _FAT_close_r (struct _reent *r, int fd) {$/;" f -_FAT_dirclose_r fatdir.c /^int _FAT_dirclose_r (struct _reent *r, DIR_ITER *dirState) {$/;" f -_FAT_directory_addEntry directory.c /^bool _FAT_directory_addEntry (PARTITION* partition, DIR_ENTRY* entry, uint32_t dirCluster) {$/;" f -_FAT_directory_chdir directory.c /^bool _FAT_directory_chdir (PARTITION* partition, const char* path) {$/;" f -_FAT_directory_createAlias directory.c /^static int _FAT_directory_createAlias (char* alias, const char* lfn) {$/;" f file: -_FAT_directory_entryExists directory.c /^static bool _FAT_directory_entryExists (PARTITION* partition, const char* name, uint32_t dirCluster) {$/;" f file: -_FAT_directory_entryFromPath directory.c /^bool _FAT_directory_entryFromPath (PARTITION* partition, DIR_ENTRY* entry, const char* path, const char* pathEnd) {$/;" f -_FAT_directory_entryFromPosition directory.c /^bool _FAT_directory_entryFromPosition (PARTITION* partition, DIR_ENTRY* entry) {$/;" f -_FAT_directory_entryGetAlias directory.c /^static bool _FAT_directory_entryGetAlias (const u8* entryData, char* destName) {$/;" f file: -_FAT_directory_entryGetCluster directory.c /^uint32_t _FAT_directory_entryGetCluster (PARTITION* partition, const uint8_t* entryData) {$/;" f -_FAT_directory_entryStat directory.c /^void _FAT_directory_entryStat (PARTITION* partition, DIR_ENTRY* entry, struct stat *st) {$/;" f -_FAT_directory_findEntryGap directory.c /^static bool _FAT_directory_findEntryGap (PARTITION* partition, DIR_ENTRY* entry, uint32_t dirCluster, size_t size) {$/;" f file: -_FAT_directory_getFirstEntry directory.c /^bool _FAT_directory_getFirstEntry (PARTITION* partition, DIR_ENTRY* entry, uint32_t dirCluster) {$/;" f -_FAT_directory_getNextEntry directory.c /^bool _FAT_directory_getNextEntry (PARTITION* partition, DIR_ENTRY* entry) {$/;" f -_FAT_directory_getRootEntry directory.c /^bool _FAT_directory_getRootEntry (PARTITION* partition, DIR_ENTRY* entry) {$/;" f -_FAT_directory_incrementDirEntryPosition directory.c /^static bool _FAT_directory_incrementDirEntryPosition (PARTITION* partition, DIR_ENTRY_POSITION* entryPosition, bool extendDirectory) {$/;" f file: -_FAT_directory_isDirectory directory.h /^static inline bool _FAT_directory_isDirectory (DIR_ENTRY* entry) {$/;" f -_FAT_directory_isDot directory.h /^static inline bool _FAT_directory_isDot (DIR_ENTRY* entry) {$/;" f -_FAT_directory_isWritable directory.h /^static inline bool _FAT_directory_isWritable (DIR_ENTRY* entry) {$/;" f -_FAT_directory_lfnLength directory.c /^static int _FAT_directory_lfnLength (const char* name) {$/;" f file: -_FAT_directory_mbsncasecmp directory.c /^static int _FAT_directory_mbsncasecmp (const char* s1, const char* s2, size_t len1) {$/;" f file: -_FAT_directory_mbstoucs2 directory.c /^static size_t _FAT_directory_mbstoucs2 (ucs2_t* dst, const char* src, size_t len) {$/;" f file: -_FAT_directory_removeEntry directory.c /^bool _FAT_directory_removeEntry (PARTITION* partition, DIR_ENTRY* entry) {$/;" f -_FAT_directory_ucs2tombs directory.c /^static size_t _FAT_directory_ucs2tombs (char* dst, const ucs2_t* src, size_t len) {$/;" f file: -_FAT_dirnext_r fatdir.c /^int _FAT_dirnext_r (struct _reent *r, DIR_ITER *dirState, char *filename, struct stat *filestat) {$/;" f -_FAT_diropen_r fatdir.c /^DIR_ITER* _FAT_diropen_r(struct _reent *r, DIR_ITER *dirState, const char *path) {$/;" f -_FAT_dirreset_r fatdir.c /^int _FAT_dirreset_r (struct _reent *r, DIR_ITER *dirState) {$/;" f -_FAT_disc_clearStatus disc.h /^static inline bool _FAT_disc_clearStatus (const DISC_INTERFACE* disc) {$/;" f -_FAT_disc_features disc.h /^static inline uint32_t _FAT_disc_features (const DISC_INTERFACE* disc) {$/;" f -_FAT_disc_hostType disc.h /^static inline uint32_t _FAT_disc_hostType (const DISC_INTERFACE* disc) {$/;" f -_FAT_disc_interfaces disc.c /^const INTERFACE_ID _FAT_disc_interfaces[] = {$/;" v -_FAT_disc_isInserted disc.h /^static inline bool _FAT_disc_isInserted (const DISC_INTERFACE* disc) {$/;" f -_FAT_disc_readSectors disc.h /^static inline bool _FAT_disc_readSectors (const DISC_INTERFACE* disc, sec_t sector, sec_t numSectors, void* buffer) {$/;" f -_FAT_disc_shutdown disc.h /^static inline bool _FAT_disc_shutdown (const DISC_INTERFACE* disc) {$/;" f -_FAT_disc_startup disc.h /^static inline bool _FAT_disc_startup (const DISC_INTERFACE* disc) {$/;" f -_FAT_disc_writeSectors disc.h /^static inline bool _FAT_disc_writeSectors (const DISC_INTERFACE* disc, sec_t sector, sec_t numSectors, const void* buffer) {$/;" f -_FAT_fat_clearLinks file_allocation_table.c /^bool _FAT_fat_clearLinks (PARTITION* partition, uint32_t cluster) {$/;" f -_FAT_fat_clusterToSector file_allocation_table.h /^static inline sec_t _FAT_fat_clusterToSector (PARTITION* partition, uint32_t cluster) {$/;" f -_FAT_fat_freeClusterCount file_allocation_table.c /^unsigned int _FAT_fat_freeClusterCount (PARTITION* partition) {$/;" f -_FAT_fat_isValidCluster file_allocation_table.h /^static inline bool _FAT_fat_isValidCluster (PARTITION* partition, uint32_t cluster) {$/;" f -_FAT_fat_lastCluster file_allocation_table.c /^uint32_t _FAT_fat_lastCluster (PARTITION* partition, uint32_t cluster) {$/;" f -_FAT_fat_linkFreeCluster file_allocation_table.c /^uint32_t _FAT_fat_linkFreeCluster(PARTITION* partition, uint32_t cluster) {$/;" f -_FAT_fat_linkFreeClusterCleared file_allocation_table.c /^uint32_t _FAT_fat_linkFreeClusterCleared (PARTITION* partition, uint32_t cluster) {$/;" f -_FAT_fat_nextCluster file_allocation_table.c /^uint32_t _FAT_fat_nextCluster(PARTITION* partition, uint32_t cluster)$/;" f -_FAT_fat_trimChain file_allocation_table.c /^uint32_t _FAT_fat_trimChain (PARTITION* partition, uint32_t startCluster, unsigned int chainLength) {$/;" f -_FAT_fat_writeFatEntry file_allocation_table.c /^static bool _FAT_fat_writeFatEntry (PARTITION* partition, uint32_t cluster, uint32_t value) {$/;" f file: -_FAT_file_extend_r fatfile.c /^static bool _FAT_file_extend_r (struct _reent *r, FILE_STRUCT* file) {$/;" f file: -_FAT_filetime_getDateFromRTC filetime.c /^uint16_t _FAT_filetime_getDateFromRTC (void) {$/;" f -_FAT_filetime_getTimeFromRTC filetime.c /^uint16_t _FAT_filetime_getTimeFromRTC (void) {$/;" f -_FAT_filetime_to_time_t filetime.c /^time_t _FAT_filetime_to_time_t (uint16_t t, uint16_t d) {$/;" f -_FAT_fstat_r fatfile.c /^int _FAT_fstat_r (struct _reent *r, int fd, struct stat *st) {$/;" f -_FAT_fsync_r fatfile.c /^int _FAT_fsync_r (struct _reent *r, int fd) {$/;" f -_FAT_ftruncate_r fatfile.c /^int _FAT_ftruncate_r (struct _reent *r, int fd, off_t len) {$/;" f -_FAT_link_r fatdir.c /^int _FAT_link_r (struct _reent *r, const char *existing, const char *newLink) {$/;" f -_FAT_lock lock.h /^static inline void _FAT_lock(mutex_t *mutex)$/;" f -_FAT_lock_deinit lock.h /^static inline void _FAT_lock_deinit(mutex_t *mutex)$/;" f -_FAT_lock_init lock.h /^static inline void _FAT_lock_init(mutex_t *mutex)$/;" f -_FAT_mem_align mem_allocate.h /^static inline void* _FAT_mem_align (size_t size) {$/;" f -_FAT_mem_allocate mem_allocate.h /^static inline void* _FAT_mem_allocate (size_t size) {$/;" f -_FAT_mem_free mem_allocate.h /^static inline void _FAT_mem_free (void* mem) {$/;" f -_FAT_mkdir_r fatdir.c /^int _FAT_mkdir_r (struct _reent *r, const char *path, int mode) {$/;" f -_FAT_open_r fatfile.c /^int _FAT_open_r (struct _reent *r, void *fileStruct, const char *path, int flags, int mode) {$/;" f -_FAT_partition_constructor partition.c /^PARTITION* _FAT_partition_constructor (const DISC_INTERFACE* disc, uint32_t cacheSize, uint32_t sectorsPerPage, sec_t startSector) {$/;" f -_FAT_partition_destructor partition.c /^void _FAT_partition_destructor (PARTITION* partition) {$/;" f -_FAT_partition_getPartitionFromPath partition.c /^PARTITION* _FAT_partition_getPartitionFromPath (const char* path) {$/;" f -_FAT_read_r fatfile.c /^ssize_t _FAT_read_r (struct _reent *r, int fd, char *ptr, size_t len) {$/;" f -_FAT_rename_r fatdir.c /^int _FAT_rename_r (struct _reent *r, const char *oldName, const char *newName) {$/;" f -_FAT_seek_r fatfile.c /^off_t _FAT_seek_r (struct _reent *r, int fd, off_t pos, int dir) {$/;" f -_FAT_startSector partition.c /^sec_t _FAT_startSector;$/;" v -_FAT_stat_r fatdir.c /^int _FAT_stat_r (struct _reent *r, const char *path, struct stat *st) {$/;" f -_FAT_statvfs_r fatdir.c /^int _FAT_statvfs_r (struct _reent *r, const char *path, struct statvfs *buf) $/;" f -_FAT_syncToDisc fatfile.c /^int _FAT_syncToDisc (FILE_STRUCT* file) {$/;" f -_FAT_unlink_r fatdir.c /^int _FAT_unlink_r (struct _reent *r, const char *path) {$/;" f -_FAT_unlock lock.h /^static inline void _FAT_unlock(mutex_t *mutex)$/;" f -_FAT_write_r fatfile.c /^ssize_t _FAT_write_r (struct _reent *r, int fd, const char *ptr, size_t len) {$/;" f -_FILETIME_H filetime.h 30;" d -_FILE_STRUCT fatfile.h /^struct _FILE_STRUCT {$/;" s -_LOCK_H lock.h 30;" d -_MEM_ALLOCATE_H mem_allocate.h 32;" d -_PARTITION_H partition.h 31;" d -accessCounter cache.c /^static u32 accessCounter = 0;$/;" v file: -accessTime cache.c /^static u32 accessTime(){$/;" f file: -append fatfile.h /^ bool append;$/;" m struct:_FILE_STRUCT -appendPosition fatfile.h /^ FILE_POSITION appendPosition;$/;" m struct:_FILE_STRUCT -byte fatfile.h /^ s32 byte;$/;" m struct:__anon8 -bytesPerCluster partition.h /^ uint32_t bytesPerCluster;$/;" m struct:__anon11 -bytesPerSector partition.h /^ uint32_t bytesPerSector;$/;" m struct:__anon11 -cache cache.h /^ uint8_t* cache;$/;" m struct:__anon1 -cache partition.h /^ CACHE* cache;$/;" m struct:__anon11 -cacheEntries cache.h /^ CACHE_ENTRY* cacheEntries;$/;" m struct:__anon2 -cluster directory.h /^ uint32_t cluster;$/;" m struct:__anon4 -cluster fatfile.h /^ u32 cluster;$/;" m struct:__anon8 -count cache.h /^ unsigned int count;$/;" m struct:__anon1 -currentEntry fatdir.h /^ DIR_ENTRY currentEntry;$/;" m struct:__anon7 -currentPosition fatfile.h /^ uint32_t currentPosition;$/;" m struct:_FILE_STRUCT -cwdCluster partition.h /^ uint32_t cwdCluster; \/\/ Current working directory cluster$/;" m struct:__anon11 -dataEnd directory.h /^ DIR_ENTRY_POSITION dataEnd; \/\/ Always points to the file\/directory's alias entry$/;" m struct:__anon5 -dataStart directory.h /^ DIR_ENTRY_POSITION dataStart; \/\/ Points to the start of the LFN entries of a file, or the alias for no LFN$/;" m struct:__anon5 -dataStart partition.h /^ sec_t dataStart;$/;" m struct:__anon11 -dirEntryEnd fatfile.h /^ DIR_ENTRY_POSITION dirEntryEnd; \/\/ Always points to the file's alias entry$/;" m struct:_FILE_STRUCT -dirEntryStart fatfile.h /^ DIR_ENTRY_POSITION dirEntryStart; \/\/ Points to the start of the LFN entries of a file, or the alias for no LFN$/;" m struct:_FILE_STRUCT -dirty cache.h /^ bool dirty;$/;" m struct:__anon1 -disc cache.h /^ const DISC_INTERFACE* disc;$/;" m struct:__anon2 -disc partition.h /^ const DISC_INTERFACE* disc;$/;" m struct:__anon11 -dotab_fat libfat.c /^static const devoptab_t dotab_fat = {$/;" v file: -endOfPartition cache.h /^ sec_t endOfPartition;$/;" m struct:__anon2 -entryData directory.h /^ uint8_t entryData[DIR_ENTRY_DATA_SIZE];$/;" m struct:__anon5 -fat partition.h /^ FAT fat;$/;" m struct:__anon11 -fatInit libfat.c /^bool fatInit (uint32_t cacheSize, bool setAsDefaultDevice) {$/;" f -fatInitDefault libfat.c /^bool fatInitDefault (void) {$/;" f -fatMount libfat.c /^bool fatMount (const char* name, const DISC_INTERFACE* interface, sec_t startSector, uint32_t cacheSize, uint32_t SectorsPerPage) {$/;" f -fatMountSimple libfat.c /^bool fatMountSimple (const char* name, const DISC_INTERFACE* interface) {$/;" f -fatStart partition.h /^ sec_t fatStart;$/;" m struct:__anon10 -fatUnmount libfat.c /^void fatUnmount (const char* name) {$/;" f -filename directory.h /^ char filename[MAX_FILENAME_LENGTH];$/;" m struct:__anon5 -filesize fatfile.h /^ uint32_t filesize;$/;" m struct:_FILE_STRUCT -filesysType partition.h /^ FS_TYPE filesysType;$/;" m struct:__anon11 -firstFree partition.h /^ uint32_t firstFree;$/;" m struct:__anon10 -firstOpenFile partition.h /^ struct _FILE_STRUCT* firstOpenFile; \/\/ The start of a linked list of files$/;" m struct:__anon11 typeref:struct:__anon11::_FILE_STRUCT -getInterface disc.h /^ const DISC_INTERFACE* (*getInterface)(void);$/;" m struct:__anon6 -get_io_gcsda disc.c /^static const DISC_INTERFACE* get_io_gcsda (void) {$/;" f file: -get_io_gcsdb disc.c /^static const DISC_INTERFACE* get_io_gcsdb (void) {$/;" f file: -get_io_usbstorage disc.c /^static const DISC_INTERFACE* get_io_usbstorage (void) {$/;" f file: -get_io_wiisd disc.c /^static const DISC_INTERFACE* get_io_wiisd (void) {$/;" f file: -inUse fatdir.h /^ bool inUse;$/;" m struct:__anon7 -inUse fatfile.h /^ bool inUse;$/;" m struct:_FILE_STRUCT -lastCluster partition.h /^ uint32_t lastCluster;$/;" m struct:__anon10 -last_access cache.h /^ unsigned int last_access;$/;" m struct:__anon1 -lock partition.h /^ mutex_t lock; \/\/ A lock for partition operations$/;" m struct:__anon11 -modified fatfile.h /^ bool modified;$/;" m struct:_FILE_STRUCT -mutex_t lock.h /^typedef int mutex_t;$/;" t -name disc.h /^ const char* name; $/;" m struct:__anon6 -nextOpenFile fatfile.h /^ struct _FILE_STRUCT* nextOpenFile; \/\/ The next entry in a double-linked list of open files$/;" m struct:_FILE_STRUCT typeref:struct:_FILE_STRUCT::_FILE_STRUCT -numberOfPages cache.h /^ unsigned int numberOfPages;$/;" m struct:__anon2 -numberOfSectors partition.h /^ uint32_t numberOfSectors;$/;" m struct:__anon11 -offset directory.h /^ int32_t offset;$/;" m struct:__anon4 -openFileCount partition.h /^ int openFileCount;$/;" m struct:__anon11 -partition fatdir.h /^ PARTITION* partition;$/;" m struct:__anon7 -partition fatfile.h /^ PARTITION* partition;$/;" m struct:_FILE_STRUCT -prevOpenFile fatfile.h /^ struct _FILE_STRUCT* prevOpenFile; \/\/ The previous entry in a double-linked list of open files$/;" m struct:_FILE_STRUCT typeref:struct:_FILE_STRUCT::_FILE_STRUCT -read fatfile.h /^ bool read;$/;" m struct:_FILE_STRUCT -readOnly partition.h /^ bool readOnly; \/\/ If this is set, then do not try writing to the disc$/;" m struct:__anon11 -rootDirCluster partition.h /^ uint32_t rootDirCluster;$/;" m struct:__anon11 -rootDirStart partition.h /^ sec_t rootDirStart;$/;" m struct:__anon11 -rwPosition fatfile.h /^ FILE_POSITION rwPosition;$/;" m struct:_FILE_STRUCT -sector cache.h /^ sec_t sector;$/;" m struct:__anon1 -sector directory.h /^ sec_t sector;$/;" m struct:__anon4 -sector fatfile.h /^ sec_t sector;$/;" m struct:__anon8 -sectorsPerCluster partition.h /^ uint32_t sectorsPerCluster;$/;" m struct:__anon11 -sectorsPerFat partition.h /^ uint32_t sectorsPerFat;$/;" m struct:__anon10 -sectorsPerPage cache.h /^ unsigned int sectorsPerPage;$/;" m struct:__anon2 -startCluster fatdir.h /^ uint32_t startCluster;$/;" m struct:__anon7 -startCluster fatfile.h /^ uint32_t startCluster;$/;" m struct:_FILE_STRUCT -totalSize partition.h /^ uint64_t totalSize;$/;" m struct:__anon11 -u16_to_u8array bit_ops.h /^static inline void u16_to_u8array (uint8_t* item, int offset, uint16_t value) {$/;" f -u32_to_u8array bit_ops.h /^static inline void u32_to_u8array (uint8_t* item, int offset, uint32_t value) {$/;" f -u8array_to_u16 bit_ops.h /^static inline uint16_t u8array_to_u16 (const uint8_t* item, int offset) {$/;" f -u8array_to_u32 bit_ops.h /^static inline uint32_t u8array_to_u32 (const uint8_t* item, int offset) {$/;" f -ucs2_t directory.c /^typedef unsigned short ucs2_t;$/;" t file: -validEntry fatdir.h /^ bool validEntry;$/;" m struct:__anon7 -write fatfile.h /^ bool write;$/;" m struct:_FILE_STRUCT diff --git a/cube/swiss/source/devices/fat/frag.c b/cube/swiss/source/devices/fat/frag.c deleted file mode 100644 index 6dc1b0fe..00000000 --- a/cube/swiss/source/devices/fat/frag.c +++ /dev/null @@ -1,100 +0,0 @@ -/** - * Frag.c - * - * Borrowed from cfg-loader, thanks guys. - * Adapted for swiss :) -**/ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include "frag.h" - -#include "swiss.h" -#include "main.h" -#include "gui/IPLFontWrite.h" - -FragList *frag_list = NULL; - -typedef int (*_frag_append_t)(void *ff, u32 offset, u32 sector, u32 count); - -//extern from modified libfat -int _FAT_get_fragments (const char *path, _frag_append_t append_fragment, void *callback_data); - -void frag_init(FragList *ff, int maxnum) -{ - memset(ff, 0, sizeof(Fragment) * (maxnum+1)); - ff->maxnum = maxnum; -} - -void frag_print(FragList *ff) -{ - int i; - print_gecko("frag list: %d %d %x\r\n", ff->num, ff->size, ff->size); - - for (i=0; inum; i++) { - if (i>10) { - print_gecko("...\n"); - break; - } - print_gecko(" %d : %8x %8x %8x (%i bytes)\r\n", i,ff->frag[i].offset,ff->frag[i].count,ff->frag[i].sector, ff->frag[i].count*512); - } -} - -int frag_append(FragList *ff, u32 offset, u32 sector, u32 count) -{ - int n; - if (count) { - n = ff->num - 1; - if (ff->num > 0 - && ff->frag[n].offset + ff->frag[n].count == offset - && ff->frag[n].sector + ff->frag[n].count == sector) - { - // merge - ff->frag[n].count += count; - } - else - { - // add - if (ff->num >= ff->maxnum) { - // too many fragments - return -500; - } - n = ff->num; - ff->frag[n].offset = offset; - ff->frag[n].sector = sector; - ff->frag[n].count = count; - ff->num++; - } - } - ff->size = offset + count; - return 0; -} - -int _frag_append(void *ff, u32 offset, u32 sector, u32 count) -{ - return frag_append(ff, offset, sector, count); -} - -void get_frag_list(char *path) -{ - FragList *fs = NULL; - - fs = malloc(sizeof(FragList)); - frag_init(fs, MAX_FRAG); - _FAT_get_fragments(path, &_frag_append, fs); - - if(frag_list) free(frag_list); - frag_list = malloc(sizeof(FragList)); - frag_init(frag_list, MAX_FRAG); - memcpy(frag_list, fs, sizeof(FragList)); - - free(fs); -// frag_print(frag_list); -} diff --git a/cube/swiss/source/devices/fat/frag.h b/cube/swiss/source/devices/fat/frag.h deleted file mode 100644 index 09457997..00000000 --- a/cube/swiss/source/devices/fat/frag.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef FRAG_H_ -#define FRAG_H_ - -#define MAX_FRAG 20000 //20000*12b = 240kb - -typedef struct -{ - u32 offset; // file offset, in sectors unit - u32 sector; - u32 count; -} Fragment; - -typedef struct -{ - u32 size; // num sectors - u32 num; // num fragments - u32 maxnum; - Fragment frag[MAX_FRAG]; -} FragList; - -extern FragList *frag_list; - -void frag_init(FragList *ff, int maxnum); -void get_frag_list(char *path); -#endif diff --git a/cube/swiss/source/swiss.c b/cube/swiss/source/swiss.c index 7fd8a031..ca05eead 100644 --- a/cube/swiss/source/swiss.c +++ b/cube/swiss/source/swiss.c @@ -24,7 +24,6 @@ #include #include -#include "frag.h" #include "swiss.h" #include "main.h" #include "httpd.h"