mirror of
https://github.com/wiiu-env/WiiUPluginSystem.git
synced 2024-11-16 15:49:23 +01:00
[Plugins] Started on creating a SDCafiine plugin. Still WIP.
- Stiil need to add iosuhax support (probably thrpugh iosuhax n the loader) - modpack chooser needs complety rewritten in C =( So currently this is only compatible with games with nativ sd access. Probably unstable!
This commit is contained in:
parent
2cbc49b030
commit
ac912010f2
12
.travis.yml
12
.travis.yml
@ -23,12 +23,22 @@ before_install:
|
||||
- wget http://download.sourceforge.net/devkitpro/devkitPPC_r29-1-x86_64-linux.tar.bz2 -O devkitPPC-linux.tar.bz2
|
||||
- wget https://github.com/Maschell/dynamic_libs/archive/lib.tar.gz -O dynamic_libs.tar.gz
|
||||
- wget https://github.com/Maschell/libutils/archive/master.tar.gz -O libutils.tar.gz
|
||||
- wget https://github.com/aliaspider/libfat/archive/master.tar.gz -O libfat.tar.gz
|
||||
- wget https://github.com/dimok789/libiosuhax/archive/master.tar.gz -O libiosuhax.tar.gz
|
||||
- wget https://github.com/Maschell/libntfs-wiiu/archive/master.tar.gz -O libntfs.tar.gz
|
||||
|
||||
install:
|
||||
- tar -xjf devkitPPC-linux.tar.bz2 -C ${DEVKITPRO}/
|
||||
- tar -xzvf dynamic_libs.tar.gz
|
||||
- tar -xzvf libutils.tar.gz
|
||||
- tar -xzvf libfat.tar.gz
|
||||
- tar -xzvf libiosuhax.tar.gz
|
||||
- tar -xzvf libntfs.tar.gz
|
||||
- tar -xzvf libiosuhax.tar.gz
|
||||
- 7z x -y ./dynamic_libs-lib/libs/portlibs.zip -o${DEVKITPRO}
|
||||
- (cd libiosuhax-master && make -j8 && make install)
|
||||
- (cd libfat-master && make wiiu-release && make wiiu-install)
|
||||
- (cd libntfs-wiiu-master && make wiiu-install)
|
||||
- (cd dynamic_libs-lib && make -j8 && make install)
|
||||
- (cd libutils-master && make -j8 && make install)
|
||||
|
||||
@ -37,6 +47,7 @@ script:
|
||||
- (cd loader && make)
|
||||
- (cd example_plugin && make)
|
||||
- (cd plugins/padcon && make)
|
||||
- (cd plugins/sdcafiine && make)
|
||||
|
||||
before_deploy:
|
||||
- mkdir -p "wiiu/apps/wiiupluginloader"
|
||||
@ -47,6 +58,7 @@ before_deploy:
|
||||
- (cd loader && make)
|
||||
- cp example_plugin/example_plugin.mod wiiu/plugins
|
||||
- cp plugins/padcon/padcon.mod wiiu/plugins
|
||||
- cp plugins/sdcafiine/sdcafiine.mod wiiu/plugins
|
||||
- cp loader/meta/* wiiu/apps/wiiupluginloader
|
||||
- cp loader/wiiupluginloader.elf wiiu/apps/wiiupluginloader
|
||||
- zip -r WiiUPluginLoader_$versiontag.zip wiiu
|
||||
|
289
plugins/sdcafiine/Makefile
Normal file
289
plugins/sdcafiine/Makefile
Normal file
@ -0,0 +1,289 @@
|
||||
DO_LOGGING := 1
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# Clear the implicit built in rules
|
||||
#---------------------------------------------------------------------------------
|
||||
.SUFFIXES:
|
||||
#---------------------------------------------------------------------------------
|
||||
ifeq ($(strip $(DEVKITPPC)),)
|
||||
$(error "Please set DEVKITPPC in your environment. export DEVKITPPC=<path to>devkitPPC")
|
||||
endif
|
||||
ifeq ($(strip $(DEVKITPRO)),)
|
||||
$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=<path to>devkitPRO")
|
||||
endif
|
||||
export PATH := $(DEVKITPPC)/bin:$(PORTLIBS)/bin:$(PATH)
|
||||
export PORTLIBS := $(DEVKITPRO)/portlibs/ppc
|
||||
export WUPSDIR := $(DEVKITPRO)/wups
|
||||
export GCC_VER := $(shell $(DEVKITPPC)/bin/powerpc-eabi-gcc -dumpversion)
|
||||
|
||||
PREFIX := powerpc-eabi-
|
||||
|
||||
export AS := $(PREFIX)as
|
||||
export CC := $(PREFIX)gcc
|
||||
export CXX := $(PREFIX)g++
|
||||
export LD := $(PREFIX)ld
|
||||
export AR := $(PREFIX)ar
|
||||
export OBJCOPY := $(PREFIX)objcopy
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# TARGET is the name of the output
|
||||
# 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
|
||||
#---------------------------------------------------------------------------------
|
||||
TARGET := $(notdir $(CURDIR)).mod
|
||||
BUILD := build
|
||||
SOURCES := src
|
||||
|
||||
DATA :=
|
||||
|
||||
INCLUDES := src
|
||||
|
||||
MAP ?= $(TARGET:.mod=.map)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# options for code generation
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
# -Os: optimise size
|
||||
# -Wall: generate lots of warnings
|
||||
# -DGEKKO_U: define the symbol GEKKO (used in some headers)
|
||||
# -D__wiiu__: define the symbol __wii__ (used in some headers)
|
||||
# -mrvl: enable wii/gamecube compilation
|
||||
# -mcpu=750: enable processor specific compilation
|
||||
# -meabi: enable eabi specific compilation
|
||||
# -mhard-float: enable hardware floating point instructions
|
||||
# -fshort-wchar: use 16 bit whcar_t type in keeping with Wii executables
|
||||
# -fno-common: stop common variables which the loader can't understand
|
||||
# -msdata-none: do not use r2 or r13 as small data areas
|
||||
# -memb: enable embedded application specific compilation
|
||||
# -ffunction-sections: split up functions so linker can garbage collect
|
||||
# -fdata-sections: split up data so linker can garbage collect
|
||||
COMMON_CFLAGS += -Os -Wall -DGEKKO_U -D__wiiu__ -mrvl -mcpu=750 -meabi -mhard-float -fshort-wchar -fno-common -msdata=none -memb -ffunction-sections -fdata-sections
|
||||
|
||||
|
||||
# -x c: compile as c code
|
||||
# -std=c11: use the c11 standard
|
||||
CFLAGS += $(COMMON_CFLAGS) -x c -std=c11
|
||||
|
||||
# -x c: compile as c++ code
|
||||
# -std=gnu++11: use the c++11 standard
|
||||
CXXFLAGS += $(COMMON_CFLAGS) -x c++ -std=gnu++11
|
||||
|
||||
ifeq ($(DO_LOGGING), 1)
|
||||
CFLAGS += -D__LOGGING__
|
||||
CXXFLAGS += -D__LOGGING__
|
||||
endif
|
||||
|
||||
ASFLAGS := -mregnames
|
||||
# --relocatable: make sure ld doesn't remove relocations wups will need
|
||||
# -s: strip local symbols to speed linking
|
||||
# -u: keep certain sections
|
||||
# -wrap: wrap function
|
||||
# --gc-sections: remove unneeded symbols
|
||||
# -T: use the linker script specified (to force certain wups sections together)
|
||||
# -Map: generate a map file
|
||||
|
||||
LDFLAG_COMMON += -u wups_load -u wups_meta -u wups_hooks -T $(WUPSDIR)/wups.ld \
|
||||
-Wl,-Map,$(notdir $@).map,-wrap,malloc,-wrap,free,-wrap,memalign,-wrap,calloc,-wrap,realloc,-wrap,malloc_usable_size,-wrap,_malloc_r,-wrap,_free_r,-wrap,_realloc_r,-wrap,_calloc_r,-wrap,_memalign_r,-wrap,_malloc_usable_size_r,--gc-sections
|
||||
|
||||
LDFLAGS_MOD += $(LDFLAG_COMMON),--relocatable
|
||||
LDFLAGS_ELF += --relocatable -s -T $(WUPSDIR)/wups_elf.ld
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
Q := @
|
||||
MAKEFLAGS += --no-print-directory
|
||||
#---------------------------------------------------------------------------------
|
||||
# any extra libraries we wish to link with the project
|
||||
#---------------------------------------------------------------------------------
|
||||
LIBS := -lutils -ldynamiclibs
|
||||
#
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# list of directories containing libraries, this must be the top level containing
|
||||
# include and lib
|
||||
#---------------------------------------------------------------------------------
|
||||
LIBDIRS := $(DEVKITPPC)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# 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 PROJECTDIR := $(CURDIR)
|
||||
export OUTPUT := $(CURDIR)/$(TARGETDIR)/$(TARGET)
|
||||
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
|
||||
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
|
||||
export DEPSDIR := $(CURDIR)/$(BUILD)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# automatically build a list of object files for our project
|
||||
#---------------------------------------------------------------------------------
|
||||
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
|
||||
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
|
||||
sFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
|
||||
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.S)))
|
||||
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
|
||||
TTFFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.ttf)))
|
||||
PNGFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.png)))
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# use CXX for linking C++ projects, CC for standard C
|
||||
#---------------------------------------------------------------------------------
|
||||
ifeq ($(strip $(CPPFILES)),)
|
||||
export LD_MOD := $(CC)
|
||||
else
|
||||
export LD_MOD := $(CXX)
|
||||
endif
|
||||
|
||||
export OFILES := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) \
|
||||
$(sFILES:.s=.o) $(SFILES:.S=.o) \
|
||||
$(PNGFILES:.png=.png.o) $(addsuffix .o,$(BINFILES))
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# build a list of include paths
|
||||
#---------------------------------------------------------------------------------
|
||||
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
|
||||
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
|
||||
-I$(CURDIR)/$(BUILD) -I$(PORTLIBS)/include \
|
||||
-I$(PORTLIBS)/include/libutils -I$(WUPSDIR)/include
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# build a list of library paths
|
||||
#---------------------------------------------------------------------------------
|
||||
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) \
|
||||
-L$(PORTLIBS)/lib
|
||||
|
||||
export OUTPUT := $(CURDIR)/$(TARGET)
|
||||
.PHONY: $(BUILD) clean install
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
$(BUILD):
|
||||
@[ -d $@ ] || mkdir -p $@
|
||||
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
clean:
|
||||
@echo clean ...
|
||||
@rm -fr $(BUILD) $(OUTPUT).elf $(OUTPUT).bin $(BUILD_DBG).elf $(OUTPUT)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
else
|
||||
|
||||
DEPENDS := $(OFILES:.o=.d)
|
||||
|
||||
THIS_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
|
||||
|
||||
###############################################################################
|
||||
# Rule to make everything.
|
||||
PHONY += all
|
||||
|
||||
all : $(OUTPUT)
|
||||
###############################################################################
|
||||
# Special build rules
|
||||
|
||||
# Rule to make the module file.
|
||||
$(OUTPUT) : output.elf
|
||||
@echo "checking for missing symbols ..."
|
||||
@$(LD_MOD) ../$(BUILD)/output.elf $(LDFLAG_COMMON) $(LIBS) $(LIBPATHS) -o check_linking.elf
|
||||
@echo "linking ..." $@
|
||||
@$(LD_MOD) ../$(BUILD)/output.elf $(LDFLAGS_MOD) $(LIBS) $(LIBPATHS) -o $@
|
||||
|
||||
# Rule to make the module file.
|
||||
output.elf : $(OFILES)
|
||||
@echo "linking ... output.elf"
|
||||
|
||||
|
||||
@$(LD) $(OFILES) $(LDFLAGS_ELF) $(LIBS) $(LIBPATHS) -o $@
|
||||
|
||||
###############################################################################
|
||||
# Standard build rules
|
||||
#---------------------------------------------------------------------------------
|
||||
%.a:
|
||||
#---------------------------------------------------------------------------------
|
||||
@echo $(notdir $@)
|
||||
@rm -f $@
|
||||
@$(AR) -rc $@ $^
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
%.o: %.cpp
|
||||
@echo $(notdir $<)
|
||||
@$(CXX) -MMD -MP -MF $(DEPSDIR)/$*.d $(CXXFLAGS) $(INCLUDE) -c $< -o $@ $(ERROR_FILTER)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
%.o: %.c
|
||||
@echo $(notdir $<)
|
||||
@$(CC) -MMD -MP -MF $(DEPSDIR)/$*.d $(CFLAGS) $(INCLUDE) -c $< -o $@ $(ERROR_FILTER)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
%.o: %.S
|
||||
@echo $(notdir $<)
|
||||
@$(CC) -MMD -MP -MF $(DEPSDIR)/$*.d -x assembler-with-cpp $(ASFLAGS) -c $< -o $@ $(ERROR_FILTER)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
%.png.o : %.png
|
||||
@echo $(notdir $<)
|
||||
@bin2s -a 32 $< | $(AS) -o $(@)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
%.jpg.o : %.jpg
|
||||
@echo $(notdir $<)
|
||||
@bin2s -a 32 $< | $(AS) -o $(@)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
%.ttf.o : %.ttf
|
||||
@echo $(notdir $<)
|
||||
@bin2s -a 32 $< | $(AS) -o $(@)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
%.bin.o : %.bin
|
||||
@echo $(notdir $<)
|
||||
@bin2s -a 32 $< | $(AS) -o $(@)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
%.wav.o : %.wav
|
||||
@echo $(notdir $<)
|
||||
@bin2s -a 32 $< | $(AS) -o $(@)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
%.mp3.o : %.mp3
|
||||
@echo $(notdir $<)
|
||||
@bin2s -a 32 $< | $(AS) -o $(@)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
%.ogg.o : %.ogg
|
||||
@echo $(notdir $<)
|
||||
@bin2s -a 32 $< | $(AS) -o $(@)
|
||||
|
||||
###############################################################################
|
||||
# Assembly listing rules
|
||||
|
||||
# Rule to make assembly listing.
|
||||
PHONY += list
|
||||
list : $(LIST)
|
||||
|
||||
# Rule to make the listing file.
|
||||
%.list : $(TARGET)
|
||||
$(LOG)
|
||||
-$Qmkdir -p $(dir $@)
|
||||
$Q$(OBJDUMP) -d $< > $@
|
||||
|
||||
###############################################################################
|
||||
# Clean rule
|
||||
|
||||
# Rule to clean files.
|
||||
PHONY += clean
|
||||
clean :
|
||||
$Qrm -rf $(wildcard $(BUILD) $(BIN))
|
||||
|
||||
###############################################################################
|
||||
# Phony targets
|
||||
|
||||
.PHONY : $(PHONY)
|
||||
|
||||
-include $(DEPENDS)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
endif
|
||||
#---------------------------------------------------------------------------------
|
37
plugins/sdcafiine/sdcafiine.cbp
Normal file
37
plugins/sdcafiine/sdcafiine.cbp
Normal file
@ -0,0 +1,37 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
|
||||
<CodeBlocks_project_file>
|
||||
<FileVersion major="1" minor="6" />
|
||||
<Project>
|
||||
<Option title="sdcafiine" />
|
||||
<Option pch_mode="2" />
|
||||
<Option compiler="ppc-gcc" />
|
||||
<Build>
|
||||
<Target title="Debug">
|
||||
<Option output="bin/Debug/sdcafiine" prefix_auto="1" extension_auto="1" />
|
||||
<Option object_output="obj/Debug/" />
|
||||
<Option type="1" />
|
||||
<Option compiler="ppc-gcc" />
|
||||
<Compiler>
|
||||
<Add option="-g" />
|
||||
</Compiler>
|
||||
</Target>
|
||||
<Target title="Release">
|
||||
<Option output="bin/Release/sdcafiine" prefix_auto="1" extension_auto="1" />
|
||||
<Option object_output="obj/Release/" />
|
||||
<Option type="1" />
|
||||
<Option compiler="ppc-gcc" />
|
||||
<Compiler>
|
||||
<Add option="-O2" />
|
||||
</Compiler>
|
||||
</Target>
|
||||
</Build>
|
||||
<Compiler>
|
||||
<Add option="-Wall" />
|
||||
</Compiler>
|
||||
<Extensions>
|
||||
<code_completion />
|
||||
<envvars />
|
||||
<debugger />
|
||||
</Extensions>
|
||||
</Project>
|
||||
</CodeBlocks_project_file>
|
59
plugins/sdcafiine/src/common/common.h
Normal file
59
plugins/sdcafiine/src/common/common.h
Normal file
@ -0,0 +1,59 @@
|
||||
#ifndef COMMON_H
|
||||
#define COMMON_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <dynamic_libs/os_defs.h>
|
||||
|
||||
#define CAFE_OS_SD_PATH "/vol/external01"
|
||||
#define GAME_MOD_FOLDER "/sdcafiine"
|
||||
#define SD_PATH "sd:"
|
||||
#define USB_PATH "usb:"
|
||||
#define DEFAULT_NAME_PACKAGE "DEFAULT"
|
||||
#define NAME_PREFIX_SD "sd: "
|
||||
#define NAME_PREFIX_USB "usb:"
|
||||
#define WIIU_PATH "/wiiu"
|
||||
#define IP_TXT "ip.txt"
|
||||
|
||||
#define CONTENT_FOLDER "content"
|
||||
#define AOC_FOLDER "aoc"
|
||||
#define META_FOLDER "meta"
|
||||
|
||||
#define BOOT_TV_TEX_TGA "bootTvTex.tga"
|
||||
#define BOOT_DRC_TEX_TGA "bootDrcTex.tga"
|
||||
#define BOOT_SOUND_BTSND "bootSound.btsnd"
|
||||
|
||||
#define GAME_PATH_TYPE_CONTENT 1
|
||||
#define GAME_PATH_TYPE_AOC 2
|
||||
#define GAME_PATH_TYPE_STRIPPED_CONTENT 3
|
||||
|
||||
#define SDUSB_MOUNTED_NONE 0
|
||||
#define SDUSB_MOUNTED_FAKE (1<<0)
|
||||
#define SDUSB_MOUNTED_OS_SD (1<<1)
|
||||
#define SDUSB_LIBIOSU_LOADED (1<<2)
|
||||
#define SD_MOUNTED_LIBFAT (1<<3)
|
||||
#define USB_MOUNTED_LIBFAT (1<<4)
|
||||
#define USB_MOUNTED_LIBNTFS (1<<5)
|
||||
|
||||
#define FILELIST_NAME "filelist.txt"
|
||||
#define DIR_IDENTIFY "?" /* maximum length = 1*/
|
||||
#define PARENT_DIR_IDENTIFY "?.."
|
||||
|
||||
#define ELF_DATA_ADDR (*(volatile unsigned int*)(MEM_BASE + 0x1300 + 0x00))
|
||||
#define ELF_DATA_SIZE (*(volatile unsigned int*)(MEM_BASE + 0x1300 + 0x04))
|
||||
#define MAIN_ENTRY_ADDR (*(volatile unsigned int*)(MEM_BASE + 0x1400 + 0x00))
|
||||
|
||||
#ifndef EXIT_SUCCESS
|
||||
#define EXIT_SUCCESS 0
|
||||
#endif
|
||||
#define EXIT_HBL_EXIT 0xFFFFFFFE
|
||||
#define EXIT_RELAUNCH_ON_LOAD 0xFFFFFFFD
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* COMMON_H */
|
||||
|
14
plugins/sdcafiine/src/common/retain_vars.cpp
Normal file
14
plugins/sdcafiine/src/common/retain_vars.cpp
Normal file
@ -0,0 +1,14 @@
|
||||
#include "retain_vars.h"
|
||||
|
||||
u8 gUsingLibIOSUHAX __attribute__((section(".data"))) = 0;
|
||||
u8 gAppStatus __attribute__((section(".data"))) = 0;
|
||||
volatile u8 gSDInitDone __attribute__((section(".data"))) = 0;
|
||||
|
||||
char gModFolder[FS_MAX_ENTNAME_SIZE] __attribute__((section(".data")));
|
||||
//char gLastMetaPath[FS_MAX_ENTNAME_SIZE] __attribute__((section(".data")));
|
||||
|
||||
void * ntfs_mounts __attribute__((section(".data"))) = NULL;
|
||||
int ntfs_mount_count __attribute__((section(".data"))) = 0;
|
||||
|
||||
vc_vector* g_dirhandles = NULL;
|
||||
vc_vector* g_filehandles = NULL;
|
23
plugins/sdcafiine/src/common/retain_vars.h
Normal file
23
plugins/sdcafiine/src/common/retain_vars.h
Normal file
@ -0,0 +1,23 @@
|
||||
#ifndef RETAINS_VARS_H_
|
||||
#define RETAINS_VARS_H_
|
||||
#include <dynamic_libs/fs_defs.h>
|
||||
#include <dynamic_libs/os_types.h>
|
||||
#include "utils/vc_vector.h"
|
||||
|
||||
#define ASYNC_RESULT_CACHE_SIZE 50
|
||||
#define FS_QUEUE_MESSAGE_COUNT 5
|
||||
|
||||
extern u8 gUsingLibIOSUHAX;
|
||||
extern u8 gAppStatus;
|
||||
extern volatile u8 gSDInitDone;
|
||||
|
||||
extern char gModFolder[FS_MAX_ENTNAME_SIZE];
|
||||
//extern char gLastMetaPath[FS_MAX_ENTNAME_SIZE];
|
||||
|
||||
extern void * ntfs_mounts;
|
||||
extern int ntfs_mount_count;
|
||||
|
||||
extern vc_vector* g_dirhandles;
|
||||
extern vc_vector* g_filehandles;
|
||||
|
||||
#endif // RETAINS_VARS_H_
|
98
plugins/sdcafiine/src/fs_wrapper/FileReplacerUtils.cpp
Normal file
98
plugins/sdcafiine/src/fs_wrapper/FileReplacerUtils.cpp
Normal file
@ -0,0 +1,98 @@
|
||||
/****************************************************************************
|
||||
* Copyright (C) 2017 Maschell
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
****************************************************************************/
|
||||
#include "FileReplacerUtils.h"
|
||||
#include "fs_async_wrapper.h"
|
||||
#include "common/retain_vars.h"
|
||||
|
||||
OSMessageQueue lfFSQueue __attribute__((section(".data")));
|
||||
OSMessage lfFSQueueMessages[FS_QUEUE_MESSAGE_COUNT] __attribute__((section(".data")));
|
||||
|
||||
FSAsyncResult lfAsyncResultCache[ASYNC_RESULT_CACHE_SIZE] __attribute__((section(".data")));
|
||||
u8 lfAsyncResultCacheLock __attribute__((section(".data"))) = 0;
|
||||
u8 lfAsyncResultCacheCur __attribute__((section(".data"))) = 0;
|
||||
|
||||
int setErrorFlag(int error){
|
||||
int result = error;
|
||||
if(error == -1){
|
||||
result = CHECKED_WITH_ALL_ERRORS;
|
||||
}else{
|
||||
result |= CHECKED_MASK;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int checkErrorFlag(int * error){
|
||||
if(*error == CHECKED_WITH_ALL_ERRORS){
|
||||
*error = -1;
|
||||
return true;
|
||||
}else if ((*error & CHECKED_MASK) == CHECKED_MASK){
|
||||
*error &= ~CHECKED_MASK;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void addFileHandleInternal(int handle){
|
||||
vc_vector_push_back(g_filehandles, &handle);
|
||||
}
|
||||
|
||||
void removeFileHandleInternal(int handle){
|
||||
int index = 0;
|
||||
for (void* i = vc_vector_begin(g_filehandles);i != vc_vector_end(g_filehandles); i = vc_vector_next(g_filehandles, i)) {
|
||||
int val = *(int*)i;
|
||||
if(val == handle){
|
||||
vc_vector_erase(g_filehandles,index);
|
||||
return;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
bool hasFileHandleInternal(int handle){
|
||||
for (void* i = vc_vector_begin(g_filehandles);i != vc_vector_end(g_filehandles); i = vc_vector_next(g_filehandles, i)) {
|
||||
if(*(int*)i == handle){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void addDirHandleInternal(int handle){
|
||||
vc_vector_push_back(g_dirhandles, &handle);
|
||||
}
|
||||
|
||||
void removeDirHandleInternal(int handle){
|
||||
int index = 0;
|
||||
for (void* i = vc_vector_begin(g_dirhandles);i != vc_vector_end(g_dirhandles); i = vc_vector_next(g_dirhandles, i)) {
|
||||
int val = *(int*)i;
|
||||
if(val == handle){
|
||||
vc_vector_erase(g_dirhandles,index);
|
||||
return;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
bool hasDirHandleInternal(int handle){
|
||||
for (void* i = vc_vector_begin(g_dirhandles);i != vc_vector_end(g_dirhandles); i = vc_vector_next(g_dirhandles, i)) {
|
||||
if(*(int*)i == handle){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
64
plugins/sdcafiine/src/fs_wrapper/FileReplacerUtils.h
Normal file
64
plugins/sdcafiine/src/fs_wrapper/FileReplacerUtils.h
Normal file
@ -0,0 +1,64 @@
|
||||
/****************************************************************************
|
||||
* Copyright (C) 2017 Maschell
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __FILE_REPLACER_UTILS_H_
|
||||
#define __FILE_REPLACER_UTILS_H_
|
||||
|
||||
#include <dynamic_libs/fs_defs.h>
|
||||
#include <dynamic_libs/os_types.h>
|
||||
#include <system/CThread.h>
|
||||
#include "utils/vc_vector.h"
|
||||
|
||||
#include "fs_retain_vars.h"
|
||||
|
||||
#define CHECKED_WITH_ALL_ERRORS 0x10000
|
||||
#define CHECKED_MASK 0x01000
|
||||
|
||||
#define FS_WRAPPER_DEBUG_LOG 0
|
||||
|
||||
#define USE_OS_FS_FUNCTION -1337
|
||||
|
||||
|
||||
/**
|
||||
Returns a modified error flag.
|
||||
This will be used to save the information if a file/handle was already
|
||||
tried to be patched.
|
||||
The non-async function internally call the async functions, and this way
|
||||
we avoid testing it twice.
|
||||
If the result contains our mask, we just straight to the OS functions.
|
||||
**/
|
||||
int setErrorFlag(int error);
|
||||
|
||||
/**
|
||||
Check if we already checked the file/handle.
|
||||
Returns true if it was already checked (+ revert the error)
|
||||
Return false if it should be (tried) to be patched.
|
||||
**/
|
||||
int checkErrorFlag(int * error);
|
||||
|
||||
void addFileHandleInternal(int handle);
|
||||
|
||||
void removeFileHandleInternal(int handle);
|
||||
|
||||
bool hasFileHandleInternal(int handle);
|
||||
|
||||
void addDirHandleInternal(int handle);
|
||||
|
||||
void removeDirHandleInternal(int handle);
|
||||
|
||||
bool hasDirHandleInternal(int handle);
|
||||
#endif // __FILE_REPLACER_UTILS_H_
|
217
plugins/sdcafiine/src/fs_wrapper/fs_async_wrapper.cpp
Normal file
217
plugins/sdcafiine/src/fs_wrapper/fs_async_wrapper.cpp
Normal file
@ -0,0 +1,217 @@
|
||||
/****************************************************************************
|
||||
* Copyright (C) 2017 Maschell
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
****************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <utils/logger.h>
|
||||
|
||||
#include "fs_async_wrapper.h"
|
||||
|
||||
//Wii U fails to allocate memory if we do the functions async. =/
|
||||
#define DO_REAL_ASYNC 0
|
||||
|
||||
static int doFallback(CustomAsyncParamWrapper params){
|
||||
if(params.fallbackFunction != NULL){
|
||||
if(FS_WRAPPER_DEBUG_LOG){ DEBUG_FUNCTION_LINE("Calling the fallback function %08X\n",params.fallbackFunction); }
|
||||
return ((FSAsyncFallback)params.fallbackFunction)(params.fallbackParams);
|
||||
}
|
||||
|
||||
if(params.params.needToFreePath){
|
||||
free((void*)params.params.params.path);
|
||||
}
|
||||
|
||||
DEBUG_FUNCTION_LINE("No fallback function provided\n");
|
||||
//OSFatal("No fallback given."); //We don't need to free stuff, because we'll (want to) crash anyway.
|
||||
|
||||
return FS_STATUS_FATAL_ERROR;
|
||||
}
|
||||
|
||||
static int sendAsyncResult(CustomAsyncParamWrapper in, int result){
|
||||
//FileReplacerUtils::sendAsyncCommand(in.params.params.pClient, in.params.params.pCmd, in.params.params.asyncParams, result);
|
||||
|
||||
if(in.params.needToFreePath){
|
||||
free((void*)in.params.params.path);
|
||||
}
|
||||
|
||||
return FS_STATUS_OK;
|
||||
}
|
||||
|
||||
static int fs_wrapper_async_template(CustomAsyncParam params,FSAsyncCustomCallback callback, FSAsyncFallback fallback, void * fallbackParams){
|
||||
if(FS_WRAPPER_DEBUG_LOG){ DEBUG_FUNCTION_LINE("Called!\n"); }
|
||||
|
||||
CustomAsyncParamWrapper wrapper;
|
||||
memset(&wrapper,0,sizeof(CustomAsyncParamWrapper));
|
||||
|
||||
wrapper.params = params;
|
||||
|
||||
wrapper.fallbackFunction = fallback;
|
||||
wrapper.fallbackParams = (void*)fallbackParams;
|
||||
|
||||
if(!DO_REAL_ASYNC){
|
||||
return callback(wrapper);
|
||||
}
|
||||
|
||||
//TODO:!
|
||||
|
||||
/*OSMessage message;
|
||||
message.message = (u32) callback;
|
||||
message.data0 = (u32) &wrapper;
|
||||
|
||||
|
||||
//FileReplacerUtils::addFSQueueMSG(&message);*/
|
||||
|
||||
return FS_STATUS_OK;
|
||||
}
|
||||
|
||||
int fs_wrapper_FSCloseFileAsyncCallback(CustomAsyncParamWrapper params){
|
||||
if(FS_WRAPPER_DEBUG_LOG){ DEBUG_FUNCTION_LINE("Called! params: %08X \n",params); }
|
||||
//if(params == NULL){ DEBUG_FUNCTION_LINE("!!!WARNING: Given parameter was NULL\n"); }
|
||||
|
||||
OSAsyncParamWrapper * p = &(params.params.params);
|
||||
|
||||
int result = USE_OS_FS_FUNCTION;
|
||||
if((result = fs_wrapper_FSCloseFile(p->handle)) != USE_OS_FS_FUNCTION){
|
||||
return sendAsyncResult(params,result);
|
||||
}
|
||||
|
||||
return doFallback(params);
|
||||
}
|
||||
|
||||
int fs_wrapper_FSGetPosFileAsyncCallback(CustomAsyncParamWrapper params){
|
||||
if(FS_WRAPPER_DEBUG_LOG){ DEBUG_FUNCTION_LINE("Called! params: %08X \n",params); }
|
||||
//if(params == NULL){ DEBUG_FUNCTION_LINE("!!!WARNING: Given parameter was NULL\n"); }
|
||||
|
||||
OSAsyncParamWrapper * p = &(params.params.params);
|
||||
|
||||
int result = USE_OS_FS_FUNCTION;
|
||||
if((result = fs_wrapper_FSGetPosFile(p->handle,p->posPtr)) != USE_OS_FS_FUNCTION){
|
||||
return sendAsyncResult(params,result);
|
||||
}
|
||||
|
||||
return doFallback(params);
|
||||
}
|
||||
|
||||
int fs_wrapper_FSGetStatAsyncCallback(CustomAsyncParamWrapper params){
|
||||
if(FS_WRAPPER_DEBUG_LOG){ DEBUG_FUNCTION_LINE("Called! params: %08X \n",params); }
|
||||
//if(params == NULL){ DEBUG_FUNCTION_LINE("!!!WARNING: Given parameter was NULL\n"); }
|
||||
|
||||
OSAsyncParamWrapper * p = &(params.params.params);
|
||||
|
||||
int result = USE_OS_FS_FUNCTION;
|
||||
if((result = fs_wrapper_FSGetStat(p->path,p->stats)) != USE_OS_FS_FUNCTION){
|
||||
return sendAsyncResult(params,result);
|
||||
}
|
||||
|
||||
return doFallback(params);
|
||||
}
|
||||
|
||||
int fs_wrapper_FSGetStatFileAsyncCallback(CustomAsyncParamWrapper params){
|
||||
if(FS_WRAPPER_DEBUG_LOG){ DEBUG_FUNCTION_LINE("Called! params: %08X \n",params); }
|
||||
//if(params == NULL){ DEBUG_FUNCTION_LINE("!!!WARNING: Given parameter was NULL\n"); }
|
||||
|
||||
OSAsyncParamWrapper * p = &(params.params.params);
|
||||
|
||||
int result = USE_OS_FS_FUNCTION;
|
||||
if((result = fs_wrapper_FSGetStatFile(p->handle,p->stats)) != USE_OS_FS_FUNCTION){
|
||||
return sendAsyncResult(params,result);
|
||||
}
|
||||
|
||||
return doFallback(params);
|
||||
}
|
||||
|
||||
int fs_wrapper_FSIsEofAsyncCallback(CustomAsyncParamWrapper params){
|
||||
if(FS_WRAPPER_DEBUG_LOG){ DEBUG_FUNCTION_LINE("Called! params: %08X \n",params); }
|
||||
//if(params == NULL){ DEBUG_FUNCTION_LINE("!!!WARNING: Given parameter was NULL\n"); }
|
||||
|
||||
OSAsyncParamWrapper * p = &(params.params.params);
|
||||
|
||||
int result = USE_OS_FS_FUNCTION;
|
||||
if((result = fs_wrapper_FSIsEof(p->handle)) != USE_OS_FS_FUNCTION){
|
||||
return sendAsyncResult(params,result);
|
||||
}
|
||||
|
||||
return doFallback(params);
|
||||
}
|
||||
|
||||
int fs_wrapper_FSOpenFileAsyncCallback(CustomAsyncParamWrapper params){
|
||||
if(FS_WRAPPER_DEBUG_LOG){ DEBUG_FUNCTION_LINE("Called! params: %08X \n",params); }
|
||||
//if(params == NULL){ DEBUG_FUNCTION_LINE("!!!WARNING: Given parameter was NULL\n"); }
|
||||
|
||||
OSAsyncParamWrapper * p = &(params.params.params);
|
||||
|
||||
int result = USE_OS_FS_FUNCTION;
|
||||
if((result = fs_wrapper_FSOpenFile(p->path,p->mode,p->handlePtr)) != USE_OS_FS_FUNCTION){
|
||||
return sendAsyncResult(params,result);
|
||||
}
|
||||
|
||||
return doFallback(params);
|
||||
}
|
||||
|
||||
int fs_wrapper_FSReadFileAsyncCallback(CustomAsyncParamWrapper params){
|
||||
if(FS_WRAPPER_DEBUG_LOG){ DEBUG_FUNCTION_LINE("Called! params: %08X \n",params); }
|
||||
//if(params == NULL){ DEBUG_FUNCTION_LINE("!!!WARNING: Given parameter was NULL\n"); }
|
||||
|
||||
OSAsyncParamWrapper * p = &(params.params.params);
|
||||
|
||||
int result = USE_OS_FS_FUNCTION;
|
||||
if((result = fs_wrapper_FSReadFile(p->handle,p->buffer,p->size,p->count)) != USE_OS_FS_FUNCTION){
|
||||
return sendAsyncResult(params,result);
|
||||
}
|
||||
|
||||
return doFallback(params);
|
||||
}
|
||||
|
||||
int fs_wrapper_FSReadFileWithPosAsyncCallback(CustomAsyncParamWrapper params){
|
||||
if(FS_WRAPPER_DEBUG_LOG){ DEBUG_FUNCTION_LINE("Called! params: %08X \n",params); }
|
||||
//if(params == NULL){ DEBUG_FUNCTION_LINE("!!!WARNING: Given parameter was NULL\n"); }
|
||||
|
||||
OSAsyncParamWrapper * p = &(params.params.params);
|
||||
|
||||
int result = USE_OS_FS_FUNCTION;
|
||||
if((result = fs_wrapper_FSReadFileWithPos(p->buffer,p->size,p->count,p->pos,p->handle)) != USE_OS_FS_FUNCTION){
|
||||
return sendAsyncResult(params,result);
|
||||
}
|
||||
|
||||
return doFallback(params);
|
||||
}
|
||||
|
||||
int fs_wrapper_FSSetPosFileAsyncCallback(CustomAsyncParamWrapper params){
|
||||
if(FS_WRAPPER_DEBUG_LOG){ DEBUG_FUNCTION_LINE("Called! params: %08X \n",params); }
|
||||
//if(params == NULL){ DEBUG_FUNCTION_LINE("!!!WARNING: Given parameter was NULL\n"); }
|
||||
|
||||
OSAsyncParamWrapper * p = &(params.params.params);
|
||||
|
||||
int result = USE_OS_FS_FUNCTION;
|
||||
if((result = fs_wrapper_FSSetPosFile(p->handle,p->pos)) != USE_OS_FS_FUNCTION){
|
||||
return sendAsyncResult(params,result);
|
||||
}
|
||||
|
||||
return doFallback(params);
|
||||
}
|
||||
|
||||
DEFINE_FS_WRAPPER(FSCloseFileAsync)
|
||||
DEFINE_FS_WRAPPER(FSGetStatAsync)
|
||||
DEFINE_FS_WRAPPER(FSGetStatFileAsync)
|
||||
DEFINE_FS_WRAPPER(FSGetPosFileAsync)
|
||||
DEFINE_FS_WRAPPER(FSIsEofAsync)
|
||||
DEFINE_FS_WRAPPER(FSOpenFileAsync)
|
||||
DEFINE_FS_WRAPPER(FSReadFileAsync)
|
||||
DEFINE_FS_WRAPPER(FSReadFileWithPosAsync)
|
||||
DEFINE_FS_WRAPPER(FSSetPosFileAsync)
|
||||
|
124
plugins/sdcafiine/src/fs_wrapper/fs_async_wrapper.h
Normal file
124
plugins/sdcafiine/src/fs_wrapper/fs_async_wrapper.h
Normal file
@ -0,0 +1,124 @@
|
||||
/****************************************************************************
|
||||
* Copyright (C) 2017 Maschell
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __FS_ASYNC_WRAPPER_H_
|
||||
#define __FS_ASYNC_WRAPPER_H_
|
||||
|
||||
#include "FileReplacerUtils.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <dynamic_libs/fs_defs.h>
|
||||
#include <dynamic_libs/fs_functions.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "fs_sync_wrapper.h"
|
||||
|
||||
typedef int (*FSAsyncFallback)(void * params);
|
||||
|
||||
typedef struct OSAsyncParamWrapper_{
|
||||
FSClient *pClient;
|
||||
FSCmdBlock *pCmd;
|
||||
const char *path;
|
||||
const char *mode;
|
||||
FSStat * stats;
|
||||
void * buffer;
|
||||
int handle;
|
||||
int size;
|
||||
int count;
|
||||
int pos;
|
||||
int flag;
|
||||
int *handlePtr;
|
||||
int *posPtr;
|
||||
int error;
|
||||
FSAsyncParams * asyncParams;
|
||||
} OSAsyncParamWrapper;
|
||||
|
||||
typedef struct FallbackParamWrapper_{
|
||||
OSAsyncParamWrapper params;
|
||||
void * realFunctionAddress;
|
||||
} FallbackParamWrapper;
|
||||
|
||||
typedef struct CustomAsyncParam_{
|
||||
OSAsyncParamWrapper params;
|
||||
bool needToFreePath;
|
||||
} CustomAsyncParam;
|
||||
|
||||
typedef struct CustomAsyncParamWrapper_{
|
||||
CustomAsyncParam params;
|
||||
FSAsyncFallback fallbackFunction;
|
||||
void * fallbackParams;
|
||||
} CustomAsyncParamWrapper;
|
||||
|
||||
typedef int (*FSAsyncCustomCallback)(CustomAsyncParamWrapper params);
|
||||
|
||||
|
||||
#define DEFINE_FS_WRAPPER(name) \
|
||||
int fs_wrapper_##name##Ex(CustomAsyncParam params, FSAsyncFallback fallback, void * fallbackParams){\
|
||||
return fs_wrapper_async_template(params,fs_wrapper_##name##Callback,fallback,fallbackParams);\
|
||||
}\
|
||||
int fs_wrapper_##name(CustomAsyncParam params){ \
|
||||
return fs_wrapper_##name##Ex(params,NULL,NULL);\
|
||||
}
|
||||
|
||||
#define DECLARE_FS_WRAPPER(name) \
|
||||
int fs_wrapper_##name##Ex(CustomAsyncParam params, FSAsyncFallback fallback, void * fallbackParams);\
|
||||
int fs_wrapper_##name(CustomAsyncParam params);
|
||||
|
||||
int fs_wrapper_FSCloseFileAsync(CustomAsyncParam params);
|
||||
|
||||
int fs_wrapper_FSCloseFileAsyncEx(CustomAsyncParam params, FSAsyncFallback fallback, void * fallbackParams);
|
||||
|
||||
int fs_wrapper_FSGetStatAsync(CustomAsyncParam params);
|
||||
|
||||
int fs_wrapper_FSGetStatAsyncEx(CustomAsyncParam params, FSAsyncFallback fallback, void * fallbackParams);
|
||||
|
||||
int fs_wrapper_FSGetStatFileAsync(CustomAsyncParam params);
|
||||
|
||||
int fs_wrapper_FSGetStatFileAsyncEx(CustomAsyncParam params, FSAsyncFallback fallback, void * fallbackParams);
|
||||
|
||||
int fs_wrapper_FSGetPosFileAsync(CustomAsyncParam params);
|
||||
|
||||
int fs_wrapper_FSGetPosFileAsyncEx(CustomAsyncParam params, FSAsyncFallback fallback, void * fallbackParams);
|
||||
|
||||
int fs_wrapper_FSIsEofAsync(CustomAsyncParam params);
|
||||
|
||||
int fs_wrapper_FSIsEofAsyncEx(CustomAsyncParam params, FSAsyncFallback fallback, void * fallbackParams);
|
||||
|
||||
int fs_wrapper_FSOpenFileAsync(CustomAsyncParam params);
|
||||
|
||||
int fs_wrapper_FSOpenFileAsyncEx(CustomAsyncParam params, FSAsyncFallback fallback, void * fallbackParams);
|
||||
|
||||
int fs_wrapper_FSReadFileAsync(CustomAsyncParam params);
|
||||
|
||||
int fs_wrapper_FSReadFileAsyncEx(CustomAsyncParam params, FSAsyncFallback fallback, void * fallbackParams);
|
||||
|
||||
int fs_wrapper_FSReadFileWithPosAsync(CustomAsyncParam params);
|
||||
|
||||
int fs_wrapper_FSReadFileWithPosAsyncEx(CustomAsyncParam params, FSAsyncFallback fallback, void * fallbackParams);
|
||||
|
||||
int fs_wrapper_FSSetPosFileAsync(CustomAsyncParam params);
|
||||
|
||||
int fs_wrapper_FSSetPosFileAsyncEx(CustomAsyncParam params, FSAsyncFallback fallback, void * fallbackParams);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __FS_ASYNC_WRAPPER_H_
|
220
plugins/sdcafiine/src/fs_wrapper/fs_default_os_wrapper.cpp
Normal file
220
plugins/sdcafiine/src/fs_wrapper/fs_default_os_wrapper.cpp
Normal file
@ -0,0 +1,220 @@
|
||||
/****************************************************************************
|
||||
* Copyright (C) 2017 Maschell
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
****************************************************************************/
|
||||
|
||||
#include <utils/logger.h>
|
||||
|
||||
#include "fs_default_os_wrapper.h"
|
||||
|
||||
int fs_default_os_wrapper_FSCloseFileAsync(FSClient *pClient, FSCmdBlock *pCmd, int fd, int error, FSAsyncParams * asyncParams, void * realAddress){
|
||||
FallbackParamWrapper paramWrapper;
|
||||
memset(¶mWrapper,0,sizeof(FallbackParamWrapper));
|
||||
|
||||
CustomAsyncParam params;
|
||||
memset(¶ms,0,sizeof(CustomAsyncParam));
|
||||
|
||||
paramWrapper.params.pClient = pClient;
|
||||
paramWrapper.params.pCmd = pCmd;
|
||||
paramWrapper.params.handle = fd;
|
||||
paramWrapper.params.error = error;
|
||||
paramWrapper.params.asyncParams = asyncParams;
|
||||
|
||||
paramWrapper.realFunctionAddress = (void*) realAddress;
|
||||
|
||||
params.params = paramWrapper.params;
|
||||
|
||||
return fs_wrapper_FSCloseFileAsyncEx(params,&fallbackFSCloseFileAsync,¶mWrapper);
|
||||
}
|
||||
|
||||
int fs_default_os_wrapper_FSGetPosFileAsync(FSClient *pClient, FSCmdBlock *pCmd, int fd, int *pos, int error, FSAsyncParams * asyncParams, void * realAddress){
|
||||
FallbackParamWrapper paramWrapper;
|
||||
memset(¶mWrapper,0,sizeof(FallbackParamWrapper));
|
||||
|
||||
CustomAsyncParam params;
|
||||
memset(¶ms,0,sizeof(CustomAsyncParam));
|
||||
|
||||
paramWrapper.params.pClient = pClient;
|
||||
paramWrapper.params.pCmd = pCmd;
|
||||
paramWrapper.params.handle = fd;
|
||||
paramWrapper.params.posPtr = pos;
|
||||
paramWrapper.params.error = error;
|
||||
paramWrapper.params.asyncParams = asyncParams;
|
||||
|
||||
paramWrapper.realFunctionAddress = (void*) realAddress;
|
||||
|
||||
params.params = paramWrapper.params;
|
||||
|
||||
return fs_wrapper_FSGetPosFileAsyncEx(params,fallbackFSGetPosFileAsync,¶mWrapper);
|
||||
}
|
||||
|
||||
int fs_default_os_wrapper_FSGetStatAsync(const char *libPath, FSClient *pClient, FSCmdBlock *pCmd, const char *path, FSStat *stats, int error, FSAsyncParams * asyncParams, void * realAddress){
|
||||
FallbackParamWrapper paramWrapper;
|
||||
memset(¶mWrapper,0,sizeof(FallbackParamWrapper));
|
||||
|
||||
CustomAsyncParam params;
|
||||
memset(¶ms,0,sizeof(CustomAsyncParam));
|
||||
|
||||
paramWrapper.params.pClient = pClient;
|
||||
paramWrapper.params.pCmd = pCmd;
|
||||
paramWrapper.params.path = (char*)path;
|
||||
paramWrapper.params.stats = stats;
|
||||
paramWrapper.params.error = error;
|
||||
paramWrapper.params.asyncParams = asyncParams;
|
||||
|
||||
paramWrapper.realFunctionAddress = (void*) realAddress;
|
||||
|
||||
params.params = paramWrapper.params;
|
||||
params.params.path = libPath; // Use modified path.
|
||||
params.needToFreePath = 1;
|
||||
|
||||
return fs_wrapper_FSGetPosFileAsyncEx(params,fallbackFSGetStatAsync,¶mWrapper);
|
||||
}
|
||||
|
||||
int fs_default_os_wrapper_FSGetStatFileAsync(FSClient *pClient, FSCmdBlock *pCmd, int fd, FSStat * stats, int error, FSAsyncParams * asyncParams, void * realAddress){
|
||||
FallbackParamWrapper paramWrapper;
|
||||
memset(¶mWrapper,0,sizeof(FallbackParamWrapper));
|
||||
|
||||
CustomAsyncParam params;
|
||||
memset(¶ms,0,sizeof(CustomAsyncParam));
|
||||
|
||||
paramWrapper.params.pClient = pClient;
|
||||
paramWrapper.params.pCmd = pCmd;
|
||||
paramWrapper.params.handle = fd;
|
||||
paramWrapper.params.stats = stats;
|
||||
paramWrapper.params.error = error;
|
||||
paramWrapper.params.asyncParams = asyncParams;
|
||||
|
||||
paramWrapper.realFunctionAddress = (void*) realAddress;
|
||||
|
||||
params.params = paramWrapper.params;
|
||||
|
||||
return fs_wrapper_FSGetStatFileAsyncEx(params,fallbackFSGetStatFileAsync,¶mWrapper);
|
||||
}
|
||||
|
||||
int fs_default_os_wrapper_FSIsEofAsync(FSClient *pClient, FSCmdBlock *pCmd, int fd, int error, FSAsyncParams * asyncParams, void * realAddress){
|
||||
FallbackParamWrapper paramWrapper;
|
||||
memset(¶mWrapper,0,sizeof(FallbackParamWrapper));
|
||||
|
||||
CustomAsyncParam params;
|
||||
memset(¶ms,0,sizeof(CustomAsyncParam));
|
||||
|
||||
paramWrapper.params.pClient = pClient;
|
||||
paramWrapper.params.pCmd = pCmd;
|
||||
paramWrapper.params.handle = fd;
|
||||
paramWrapper.params.error = error;
|
||||
paramWrapper.params.asyncParams = asyncParams;
|
||||
|
||||
paramWrapper.realFunctionAddress = (void*) realAddress;
|
||||
|
||||
params.params = paramWrapper.params;
|
||||
|
||||
return fs_wrapper_FSIsEofAsyncEx(params,fallbackFSIsEofAsync,¶mWrapper);
|
||||
}
|
||||
|
||||
int fs_default_os_wrapper_FSOpenFileAsync(const char *libpath, FSClient *pClient, FSCmdBlock *pCmd, const char *path, const char *mode, int *handle, int error, FSAsyncParams *asyncParams, void * realAddress){
|
||||
|
||||
FallbackParamWrapper paramWrapper;
|
||||
memset(¶mWrapper,0,sizeof(FallbackParamWrapper));
|
||||
|
||||
CustomAsyncParam params;
|
||||
memset(¶ms,0,sizeof(CustomAsyncParam));
|
||||
|
||||
paramWrapper.params.pClient = pClient;
|
||||
paramWrapper.params.pCmd = pCmd;
|
||||
paramWrapper.params.path = path;
|
||||
paramWrapper.params.mode = mode;
|
||||
paramWrapper.params.handlePtr = handle;
|
||||
paramWrapper.params.error = error;
|
||||
paramWrapper.params.asyncParams = asyncParams;
|
||||
|
||||
paramWrapper.realFunctionAddress = (void*) realAddress;
|
||||
|
||||
params.params = paramWrapper.params;
|
||||
params.params.path = libpath; // Use modified path.
|
||||
params.needToFreePath = 1;
|
||||
|
||||
return fs_wrapper_FSOpenFileAsyncEx(params,fallbackFSOpenFileAsync,¶mWrapper);
|
||||
}
|
||||
|
||||
int fs_default_os_wrapper_FSReadFileAsync(FSClient *pClient, FSCmdBlock *pCmd, void *buffer, int size, int count, int fd, int flag, int error, FSAsyncParams *asyncParams, void * realAddress){
|
||||
FallbackParamWrapper paramWrapper;
|
||||
memset(¶mWrapper,0,sizeof(FallbackParamWrapper));
|
||||
|
||||
CustomAsyncParam params;
|
||||
memset(¶ms,0,sizeof(CustomAsyncParam));
|
||||
|
||||
paramWrapper.params.pClient = pClient;
|
||||
paramWrapper.params.pCmd = pCmd;
|
||||
paramWrapper.params.buffer = buffer;
|
||||
paramWrapper.params.size = size;
|
||||
paramWrapper.params.count = count;
|
||||
paramWrapper.params.handle = fd;
|
||||
paramWrapper.params.flag = flag;
|
||||
paramWrapper.params.error = error;
|
||||
paramWrapper.params.asyncParams = asyncParams;
|
||||
|
||||
paramWrapper.realFunctionAddress = (void*) realAddress;
|
||||
|
||||
params.params = paramWrapper.params;
|
||||
|
||||
return fs_wrapper_FSReadFileAsyncEx(params,fallbackFSReadFileAsync,¶mWrapper);
|
||||
}
|
||||
|
||||
int fs_default_os_wrapper_FSReadFileWithPosAsync(FSClient *pClient, FSCmdBlock *pCmd, void *buffer, int size, int count, u32 pos, int fd, int flag, int error, FSAsyncParams *asyncParams, void * realAddress){
|
||||
FallbackParamWrapper paramWrapper;
|
||||
memset(¶mWrapper,0,sizeof(FallbackParamWrapper));
|
||||
|
||||
CustomAsyncParam params;
|
||||
memset(¶ms,0,sizeof(CustomAsyncParam));
|
||||
|
||||
paramWrapper.params.pClient = pClient;
|
||||
paramWrapper.params.pCmd = pCmd;
|
||||
paramWrapper.params.buffer = buffer;
|
||||
paramWrapper.params.size = size;
|
||||
paramWrapper.params.count = count;
|
||||
paramWrapper.params.pos = pos;
|
||||
paramWrapper.params.handle = fd;
|
||||
paramWrapper.params.flag = flag;
|
||||
paramWrapper.params.error = error;
|
||||
paramWrapper.params.asyncParams = asyncParams;
|
||||
|
||||
paramWrapper.realFunctionAddress = (void*) realAddress;
|
||||
|
||||
params.params = paramWrapper.params;
|
||||
|
||||
return fs_wrapper_FSReadFileWithPosAsyncEx(params,fallbackFSReadFileWithPosAsync,¶mWrapper);
|
||||
}
|
||||
|
||||
int fs_default_os_wrapper_FSSetPosFileAsync(FSClient *pClient, FSCmdBlock *pCmd, int handle, u32 pos, int error, FSAsyncParams *asyncParams, void * realAddress){
|
||||
FallbackParamWrapper paramWrapper;
|
||||
memset(¶mWrapper,0,sizeof(FallbackParamWrapper));
|
||||
|
||||
CustomAsyncParam params;
|
||||
memset(¶ms,0,sizeof(CustomAsyncParam));
|
||||
|
||||
paramWrapper.params.pClient = pClient;
|
||||
paramWrapper.params.pCmd = pCmd;
|
||||
paramWrapper.params.handle = handle;
|
||||
paramWrapper.params.pos = pos;
|
||||
paramWrapper.params.error = error;
|
||||
paramWrapper.params.asyncParams = asyncParams;
|
||||
|
||||
paramWrapper.realFunctionAddress = (void*) realAddress;
|
||||
|
||||
params.params = paramWrapper.params;
|
||||
|
||||
return fs_wrapper_FSSetPosFileAsyncEx(params,fallbackFSSetPosFileAsync,¶mWrapper);
|
||||
}
|
43
plugins/sdcafiine/src/fs_wrapper/fs_default_os_wrapper.h
Normal file
43
plugins/sdcafiine/src/fs_wrapper/fs_default_os_wrapper.h
Normal file
@ -0,0 +1,43 @@
|
||||
/****************************************************************************
|
||||
* Copyright (C) 2017 Maschell
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __FS_DEFAULT_OS_WRAPPER_H_
|
||||
#define __FS_DEFAULT_OS_WRAPPER_H_
|
||||
|
||||
#include "fs_async_wrapper.h"
|
||||
#include "fs_sync_wrapper.h"
|
||||
#include "fs_wrapper_utils.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int fs_default_os_wrapper_FSCloseFileAsync(FSClient *pClient, FSCmdBlock *pCmd, int fd, int error, FSAsyncParams * asyncParams, void * realAddress);
|
||||
int fs_default_os_wrapper_FSGetPosFileAsync(FSClient *pClient, FSCmdBlock *pCmd, int fd, int *pos, int error, FSAsyncParams * asyncParams, void * realAddress);
|
||||
int fs_default_os_wrapper_FSGetStatAsync(const char *libpath, FSClient *pClient, FSCmdBlock *pCmd, const char *path, FSStat *stats, int error, FSAsyncParams * asyncParams, void * realAddress);
|
||||
int fs_default_os_wrapper_FSGetStatFileAsync(FSClient *pClient, FSCmdBlock *pCmd, int fd, FSStat * stats, int error, FSAsyncParams * asyncParams, void * realAddress);
|
||||
int fs_default_os_wrapper_FSIsEofAsync(FSClient *pClient, FSCmdBlock *pCmd, int fd, int error, FSAsyncParams * asyncParams, void * realAddress);
|
||||
int fs_default_os_wrapper_FSOpenFileAsync(const char *libpath, FSClient *pClient, FSCmdBlock *pCmd, const char *path, const char *mode, int *handle, int error, FSAsyncParams *asyncParams, void * realAddress);
|
||||
int fs_default_os_wrapper_FSReadFileAsync(FSClient *pClient, FSCmdBlock *pCmd, void *buffer, int size, int count, int fd, int flag, int error, FSAsyncParams *asyncParams, void * realAddress);
|
||||
int fs_default_os_wrapper_FSReadFileWithPosAsync(FSClient *pClient, FSCmdBlock *pCmd, void *buffer, int size, int count, u32 pos, int fd, int flag, int error, FSAsyncParams *asyncParams, void * realAddress);
|
||||
int fs_default_os_wrapper_FSSetPosFileAsync(FSClient *pClient, FSCmdBlock *pCmd, int handle, u32 pos, int error, FSAsyncParams *asyncParams, void * realAddress);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __FS_DEFAULT_OS_WRAPPER_H_
|
28
plugins/sdcafiine/src/fs_wrapper/fs_retain_vars.cpp
Normal file
28
plugins/sdcafiine/src/fs_wrapper/fs_retain_vars.cpp
Normal file
@ -0,0 +1,28 @@
|
||||
/****************************************************************************
|
||||
* Copyright (C) 2017 Maschell
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
****************************************************************************/
|
||||
#include <dynamic_libs/os_types.h>
|
||||
#include "fs_retain_vars.h"
|
||||
|
||||
OSMessageQueue fsFSQueue __attribute__((section(".data")));
|
||||
OSMessage fsFSQueueMessages[FS_QUEUE_MESSAGE_COUNT] __attribute__((section(".data")));
|
||||
|
||||
FSAsyncResult fsAsyncResultCache[ASYNC_RESULT_CACHE_SIZE] __attribute__((section(".data")));
|
||||
u8 fsAsyncResultCacheLock __attribute__((section(".data"))) = 0;
|
||||
u8 fsAsyncResultCacheCur __attribute__((section(".data"))) = 0;
|
||||
|
||||
u32 global_owner_id __attribute__((section(".data"))) = 0;
|
||||
u32 global_group_id __attribute__((section(".data"))) = 0;
|
38
plugins/sdcafiine/src/fs_wrapper/fs_retain_vars.h
Normal file
38
plugins/sdcafiine/src/fs_wrapper/fs_retain_vars.h
Normal file
@ -0,0 +1,38 @@
|
||||
/****************************************************************************
|
||||
* Copyright (C) 2017 Maschell
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef FS_RETAINS_VARS_H_
|
||||
#define FS_RETAINS_VARS_H_
|
||||
|
||||
#include <dynamic_libs/fs_defs.h>
|
||||
#include <dynamic_libs/os_types.h>
|
||||
|
||||
#define ASYNC_RESULT_CACHE_SIZE 50
|
||||
#define FS_QUEUE_MESSAGE_COUNT 5
|
||||
|
||||
extern OSMessageQueue fsFSQueue __attribute__((section(".data")));
|
||||
extern OSMessage fsFSQueueMessages[FS_QUEUE_MESSAGE_COUNT] __attribute__((section(".data")));
|
||||
|
||||
extern FSAsyncResult fsAsyncResultCache[ASYNC_RESULT_CACHE_SIZE];
|
||||
|
||||
extern u8 fsAsyncResultCacheLock;
|
||||
extern u8 fsAsyncResultCacheCur;
|
||||
|
||||
extern u32 global_owner_id;
|
||||
extern u32 global_group_id;
|
||||
|
||||
#endif // FS_RETAINS_VARS_H_
|
226
plugins/sdcafiine/src/fs_wrapper/fs_sync_wrapper.cpp
Normal file
226
plugins/sdcafiine/src/fs_wrapper/fs_sync_wrapper.cpp
Normal file
@ -0,0 +1,226 @@
|
||||
/****************************************************************************
|
||||
* Copyright (C) 2017 Maschell
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
****************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <utils/logger.h>
|
||||
|
||||
#include "fs_sync_wrapper.h"
|
||||
#include "fs_retain_vars.h"
|
||||
|
||||
int fs_wrapper_FSCloseFile(int handle){
|
||||
if(FS_WRAPPER_DEBUG_LOG){ DEBUG_FUNCTION_LINE("Called! for handle: %08X \n",handle); }
|
||||
if(hasFileHandleInternal(handle)){
|
||||
removeFileHandleInternal(handle);
|
||||
close(handle);
|
||||
DEBUG_FUNCTION_LINE("closed handle %08X\n",handle);
|
||||
return FS_STATUS_OK;
|
||||
}
|
||||
return USE_OS_FS_FUNCTION;
|
||||
}
|
||||
|
||||
int fs_wrapper_FSGetPosFile(int handle,int * pos){
|
||||
if(FS_WRAPPER_DEBUG_LOG){ DEBUG_FUNCTION_LINE("Called! for handle: %08X \n",handle); }
|
||||
if(hasFileHandleInternal(handle)){
|
||||
off_t currentPos = lseek(handle, (off_t)0, SEEK_CUR);
|
||||
*pos = currentPos;
|
||||
|
||||
DEBUG_FUNCTION_LINE("pos %08X for handle %08X\n",*pos,handle);
|
||||
|
||||
return FS_STATUS_OK;
|
||||
}
|
||||
return USE_OS_FS_FUNCTION;
|
||||
}
|
||||
|
||||
void setCommonStats(FSStat * stats){
|
||||
if(stats == NULL){
|
||||
DEBUG_FUNCTION_LINE("STATS EMPTY\n");
|
||||
}
|
||||
stats->permission = 0x00000400;
|
||||
stats->owner_id = global_owner_id;
|
||||
stats->group_id = global_group_id;
|
||||
stats->flag |= 0x08000000;
|
||||
stats->flag |= 0x04000000;
|
||||
stats->ctime = 0x0003E8C3E677A740L;
|
||||
stats->mtime = 0x0003F8AABBEAFBC0L;
|
||||
}
|
||||
|
||||
int fs_wrapper_FSGetStat(const char * path, FSStat * stats){
|
||||
if(FS_WRAPPER_DEBUG_LOG){ DEBUG_FUNCTION_LINE("Called!\n"); }
|
||||
int result = USE_OS_FS_FUNCTION;
|
||||
if(path != NULL){
|
||||
DEBUG_FUNCTION_LINE("Searching for path %s\n",path);
|
||||
struct stat path_stat;
|
||||
if(stat(path, &path_stat) < 0){
|
||||
result = USE_OS_FS_FUNCTION;
|
||||
if(FS_WRAPPER_DEBUG_LOG){ DEBUG_FUNCTION_LINE("failed for path %s\n",path); }
|
||||
}else{
|
||||
DEBUG_FUNCTION_LINE("success! path %s\n",path);
|
||||
stats->flag = 0;
|
||||
if(S_ISDIR(path_stat.st_mode)){
|
||||
stats->flag |= 0x80000000;
|
||||
DEBUG_FUNCTION_LINE("set stats->flag: DIR\n");
|
||||
}else{
|
||||
stats->size = path_stat.st_size;
|
||||
DEBUG_FUNCTION_LINE("stats->size: %08X\n",stats->size);
|
||||
}
|
||||
|
||||
setCommonStats(stats);
|
||||
|
||||
result = FS_STATUS_OK;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int fs_wrapper_FSGetStatFile(int handle, FSStat * stats){
|
||||
if(FS_WRAPPER_DEBUG_LOG){ DEBUG_FUNCTION_LINE("Called! for handle: %08X\n",handle); }
|
||||
if(hasFileHandleInternal(handle)){
|
||||
struct stat path_stat;
|
||||
if(fstat(handle, &path_stat) < 0){
|
||||
DEBUG_FUNCTION_LINE("failed! handle: %08X\n",handle);
|
||||
return -1;
|
||||
}
|
||||
|
||||
stats->size = path_stat.st_size;
|
||||
stats->flag = 0;
|
||||
|
||||
setCommonStats(stats);
|
||||
|
||||
DEBUG_FUNCTION_LINE("success! handle: %08X size: %08X\n",handle,stats->size);
|
||||
|
||||
return FS_STATUS_OK;
|
||||
}
|
||||
return USE_OS_FS_FUNCTION;
|
||||
}
|
||||
|
||||
int fs_wrapper_FSIsEof(int handle){
|
||||
if(FS_WRAPPER_DEBUG_LOG){ DEBUG_FUNCTION_LINE("Called! handle: %08X\n",handle); }
|
||||
int result = USE_OS_FS_FUNCTION;
|
||||
if(hasFileHandleInternal(handle)){
|
||||
off_t currentPos = lseek(handle, (off_t) 0, SEEK_CUR);
|
||||
off_t endPos = lseek(handle, (off_t) 0, SEEK_END);
|
||||
|
||||
if(currentPos == endPos){
|
||||
result = FS_STATUS_EOF;
|
||||
}else{
|
||||
lseek(handle, currentPos, SEEK_CUR);
|
||||
result = FS_STATUS_OK;
|
||||
}
|
||||
DEBUG_FUNCTION_LINE("handle: %08X result: %08X\n",handle,result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int fs_wrapper_FSOpenFile(const char * path, const char * mode, int * handle){
|
||||
int result = USE_OS_FS_FUNCTION;
|
||||
if(path != NULL){
|
||||
result = USE_OS_FS_FUNCTION;
|
||||
DEBUG_FUNCTION_LINE("Searching for path %s\n",path);
|
||||
int fd = open(path,O_RDONLY); //TODO: remove hardcoded mode.
|
||||
if(fd != -1){
|
||||
DEBUG_FUNCTION_LINE("opened path: %s handle: %08X\n",path,fd);
|
||||
addFileHandleInternal(fd);
|
||||
*handle = fd;
|
||||
result = FS_STATUS_OK;
|
||||
|
||||
}else{
|
||||
if(FS_WRAPPER_DEBUG_LOG){DEBUG_FUNCTION_LINE("failed path: %s\n",path);}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#define MAXIMUM_READ_CHUNK 1024*1024
|
||||
|
||||
static int readIntoBuffer(int handle,void *buffer,size_t size, size_t count){
|
||||
int sizeToRead = size*count;
|
||||
void * newBuffer = buffer;
|
||||
int curResult = -1;
|
||||
int totalSize = 0;
|
||||
int toRead = 0;
|
||||
while(sizeToRead > 0){
|
||||
if(sizeToRead < MAXIMUM_READ_CHUNK){
|
||||
toRead = sizeToRead;
|
||||
}else{
|
||||
toRead = MAXIMUM_READ_CHUNK;
|
||||
}
|
||||
curResult = read(handle, newBuffer,toRead);
|
||||
if(curResult < 0){
|
||||
DEBUG_FUNCTION_LINE("Error: Reading %08X bytes from handle %08X. result %08X \n",size*count,handle,curResult);
|
||||
return -1;
|
||||
}
|
||||
if(curResult == 0 ){
|
||||
//EOF
|
||||
break;
|
||||
}
|
||||
newBuffer = (void*)(((u32)newBuffer) + curResult);
|
||||
totalSize += curResult;
|
||||
sizeToRead -= curResult;
|
||||
if(sizeToRead > 0){
|
||||
DEBUG_FUNCTION_LINE("Reading. missing %08X bytes\n",sizeToRead);
|
||||
}
|
||||
}
|
||||
DEBUG_FUNCTION_LINE("Success: Read %08X bytes from handle %08X. result %08X \n",size*count,handle,totalSize);
|
||||
return totalSize;
|
||||
}
|
||||
|
||||
int fs_wrapper_FSReadFile(int handle,void *buffer,size_t size, size_t count){
|
||||
if(FS_WRAPPER_DEBUG_LOG){ DEBUG_FUNCTION_LINE("Called! for handle: %08X \n",handle); }
|
||||
int result = USE_OS_FS_FUNCTION;
|
||||
if(hasFileHandleInternal(handle)){
|
||||
result = readIntoBuffer(handle,buffer,size,count);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int fs_wrapper_FSReadFileWithPos(void *buffer, size_t size, size_t count, u32 pos, int handle){
|
||||
if(FS_WRAPPER_DEBUG_LOG){ DEBUG_FUNCTION_LINE("Called! \n"); }
|
||||
int result = USE_OS_FS_FUNCTION;
|
||||
if(hasFileHandleInternal(handle)){
|
||||
off_t newOffset = -1;
|
||||
newOffset = lseek(handle, (off_t)pos, SEEK_SET);
|
||||
if(newOffset == (off_t)pos){
|
||||
result = readIntoBuffer(handle, buffer,size,count);
|
||||
DEBUG_FUNCTION_LINE("Reading %08X bytes from handle %08X at pos %08X. result %08X \n",size*count,handle,pos,result);
|
||||
}else{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int fs_wrapper_FSSetPosFile(int handle,u32 pos){
|
||||
if(FS_WRAPPER_DEBUG_LOG){ DEBUG_FUNCTION_LINE("Called! \n"); }
|
||||
int result = USE_OS_FS_FUNCTION;
|
||||
if(hasFileHandleInternal(handle)){
|
||||
off_t newOffset = -1;
|
||||
result = -1;
|
||||
newOffset = lseek(handle, (off_t)pos, SEEK_SET);
|
||||
if(newOffset == (off_t)pos){
|
||||
result = FS_STATUS_OK;
|
||||
DEBUG_FUNCTION_LINE("Set position to %08X for handle %08X\n",pos,handle);
|
||||
}else{
|
||||
DEBUG_FUNCTION_LINE("Failed set position to %08X for handle %08X\n",pos,handle);
|
||||
return FS_STATUS_OK;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
54
plugins/sdcafiine/src/fs_wrapper/fs_sync_wrapper.h
Normal file
54
plugins/sdcafiine/src/fs_wrapper/fs_sync_wrapper.h
Normal file
@ -0,0 +1,54 @@
|
||||
/****************************************************************************
|
||||
* Copyright (C) 2017 Maschell
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __FS_SYNC_WRAPPER_H_
|
||||
#define __FS_SYNC_WRAPPER_H_
|
||||
|
||||
#include "FileReplacerUtils.h"
|
||||
|
||||
#include <dynamic_libs/fs_defs.h>
|
||||
#include <dynamic_libs/fs_functions.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int fs_wrapper_FSCloseFile(int handle);
|
||||
|
||||
int fs_wrapper_FSGetPosFile(int handle,int * pos);
|
||||
|
||||
int fs_wrapper_FSGetStat(const char * path, FSStat * stats);
|
||||
|
||||
int fs_wrapper_FSGetStatFile(int handle, FSStat * stats);
|
||||
|
||||
int fs_wrapper_FSIsEof(int handle);
|
||||
|
||||
int fs_wrapper_FSOpenFile(const char * path, const char * mode, int * handle);
|
||||
|
||||
int fs_wrapper_FSReadFile(int handle,void *buffer,size_t size,size_t count);
|
||||
|
||||
int fs_wrapper_FSReadFileWithPos(void *buffer, size_t size, size_t count, u32 pos, int handle);
|
||||
|
||||
int fs_wrapper_FSSetPosFile(int handle,u32 pos);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __FS_SYNC_WRAPPER_H_
|
108
plugins/sdcafiine/src/fs_wrapper/fs_wrapper_utils.cpp
Normal file
108
plugins/sdcafiine/src/fs_wrapper/fs_wrapper_utils.cpp
Normal file
@ -0,0 +1,108 @@
|
||||
/****************************************************************************
|
||||
* Copyright (C) 2017 Maschell
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
****************************************************************************/
|
||||
#include <utils/logger.h>
|
||||
|
||||
#include "fs_wrapper_utils.h"
|
||||
#include "fs_async_wrapper.h"
|
||||
|
||||
typedef int (*FallbackHelperInternal)(FallbackParamWrapper*, OSAsyncParamWrapper *);
|
||||
|
||||
static int fallbackCaller(FallbackHelperInternal _function, void * fallbackparams){
|
||||
FallbackParamWrapper * paramsWrapper = (FallbackParamWrapper *)fallbackparams;
|
||||
OSAsyncParamWrapper * params = &(paramsWrapper->params);
|
||||
|
||||
if(paramsWrapper->realFunctionAddress == NULL){ return FS_STATUS_FATAL_ERROR; } // OSFatal("paramsWrapper->realFunctionAddress was NULL;");}
|
||||
return _function(paramsWrapper,params);
|
||||
}
|
||||
|
||||
static int fallbackFSCloseFileAsyncInternal(FallbackParamWrapper * paramsWrapper, OSAsyncParamWrapper * params){
|
||||
int (*real_FSCloseFileAsyncCallback)(FSClient *, FSCmdBlock *, int, int, FSAsyncParams *);
|
||||
real_FSCloseFileAsyncCallback = (int(*)(FSClient *, FSCmdBlock *, int, int, FSAsyncParams *)) paramsWrapper->realFunctionAddress;
|
||||
int res = real_FSCloseFileAsyncCallback(params->pClient, params->pCmd, params->handle, params->error,params->asyncParams);
|
||||
return res;
|
||||
}
|
||||
|
||||
static int fallbackFSGetPosFileAsyncInternal(FallbackParamWrapper * paramsWrapper, OSAsyncParamWrapper * params){
|
||||
int (*real_FSGetPosFileAsyncFunc)(FSClient *, FSCmdBlock *, int, int *, int, FSAsyncParams *);
|
||||
real_FSGetPosFileAsyncFunc = (int(*)(FSClient *, FSCmdBlock *, int, int *, int, FSAsyncParams *)) paramsWrapper->realFunctionAddress;
|
||||
int res = real_FSGetPosFileAsyncFunc(params->pClient, params->pCmd, params->handle, params->posPtr, params->error,params->asyncParams);
|
||||
return res;
|
||||
}
|
||||
|
||||
static int fallbackFSGetStatAsyncInternal(FallbackParamWrapper * paramsWrapper, OSAsyncParamWrapper * params){
|
||||
int (*real_FSGetStatAsyncFunc)(FSClient *, FSCmdBlock *, const char *, FSStat *, int, FSAsyncParams *);
|
||||
real_FSGetStatAsyncFunc = (int(*)(FSClient *, FSCmdBlock *, const char *, FSStat *, int, FSAsyncParams *)) paramsWrapper->realFunctionAddress;
|
||||
int res = real_FSGetStatAsyncFunc(params->pClient, params->pCmd, params->path, params->stats, params->error,params->asyncParams);
|
||||
return res;
|
||||
}
|
||||
|
||||
static int fallbackFSGetStatFileAsyncInternal(FallbackParamWrapper * paramsWrapper, OSAsyncParamWrapper * params){
|
||||
int (*real_FSGetStatFileAsyncFunc)(FSClient *, FSCmdBlock *, int, FSStat *, int, FSAsyncParams *);
|
||||
real_FSGetStatFileAsyncFunc = (int(*)(FSClient *, FSCmdBlock *, int, FSStat *, int, FSAsyncParams *)) paramsWrapper->realFunctionAddress;
|
||||
int res = real_FSGetStatFileAsyncFunc(params->pClient, params->pCmd, params->handle, params->stats, params->error,params->asyncParams);
|
||||
return res;
|
||||
}
|
||||
|
||||
static int fallbackFSIsEofAsyncInternal(FallbackParamWrapper * paramsWrapper, OSAsyncParamWrapper * params){
|
||||
int (*real_FSIsEofAsyncFunc)(FSClient *, FSCmdBlock *, int, int, FSAsyncParams *);
|
||||
real_FSIsEofAsyncFunc = (int(*)(FSClient *, FSCmdBlock *, int, int, FSAsyncParams *)) paramsWrapper->realFunctionAddress;
|
||||
int res = real_FSIsEofAsyncFunc(params->pClient, params->pCmd, params->handle, params->error,params->asyncParams);
|
||||
return res;
|
||||
}
|
||||
|
||||
static int fallbackFSOpenFileAsyncInternal(FallbackParamWrapper * paramsWrapper, OSAsyncParamWrapper * params){
|
||||
int (*real_FSOpenFileAsyncCallback)(FSClient *, FSCmdBlock *, const char *, const char *, int *, int, FSAsyncParams *);
|
||||
real_FSOpenFileAsyncCallback = (int(*)(FSClient *, FSCmdBlock *, const char *, const char *, int *, int, FSAsyncParams *)) paramsWrapper->realFunctionAddress;
|
||||
int res = real_FSOpenFileAsyncCallback(params->pClient, params->pCmd, params->path, params->mode, params->handlePtr, params->error, params->asyncParams);
|
||||
return res;
|
||||
}
|
||||
|
||||
static int fallbackFSReadFileAsyncInternal(FallbackParamWrapper * paramsWrapper, OSAsyncParamWrapper * params){
|
||||
int (*real_FSReadFileAsyncFunc)(FSClient *, FSCmdBlock *, void *, int, int, int, int, int, FSAsyncParams *);
|
||||
real_FSReadFileAsyncFunc = (int(*)(FSClient *, FSCmdBlock *, void *, int, int, int, int, int, FSAsyncParams *)) paramsWrapper->realFunctionAddress;
|
||||
int res = real_FSReadFileAsyncFunc(params->pClient, params->pCmd, params->buffer, params->size, params->count, params->handle, params->flag, params->error, params->asyncParams);
|
||||
return res;
|
||||
}
|
||||
|
||||
static int fallbackFSReadFileWithPosAsyncInternal(FallbackParamWrapper * paramsWrapper, OSAsyncParamWrapper * params){
|
||||
int (*real_FSReadFileWithPosAsyncFunc)(FSClient *, FSCmdBlock *, void *, int, int, u32, int, int, int, FSAsyncParams *);
|
||||
real_FSReadFileWithPosAsyncFunc = (int(*)(FSClient *, FSCmdBlock *, void *, int, int, u32, int, int, int, FSAsyncParams *)) paramsWrapper->realFunctionAddress;
|
||||
int res = real_FSReadFileWithPosAsyncFunc(params->pClient, params->pCmd, params->buffer, params->size, params->count, params->pos, params->handle, params->flag, params->error, params->asyncParams);
|
||||
return res;
|
||||
}
|
||||
|
||||
static int fallbackFSSetPosFileAsyncInternal(FallbackParamWrapper * paramsWrapper, OSAsyncParamWrapper * params){
|
||||
int (*real_FSSetPosFileAsyncFunc)(FSClient *, FSCmdBlock *, int, u32, int, FSAsyncParams *);
|
||||
real_FSSetPosFileAsyncFunc = (int(*)(FSClient *, FSCmdBlock *, int, u32, int, FSAsyncParams *)) paramsWrapper->realFunctionAddress;
|
||||
int res = real_FSSetPosFileAsyncFunc(params->pClient, params->pCmd, params->handle, params->pos, params->error, params->asyncParams);
|
||||
return res;
|
||||
}
|
||||
|
||||
#define DEFINE_FS_FALLBACK_CALLER(name) \
|
||||
int fallback##name(void * fallbackparams){\
|
||||
return fallbackCaller(fallback##name##Internal,fallbackparams);\
|
||||
}
|
||||
|
||||
DEFINE_FS_FALLBACK_CALLER(FSCloseFileAsync)
|
||||
DEFINE_FS_FALLBACK_CALLER(FSGetStatAsync)
|
||||
DEFINE_FS_FALLBACK_CALLER(FSGetStatFileAsync)
|
||||
DEFINE_FS_FALLBACK_CALLER(FSGetPosFileAsync)
|
||||
DEFINE_FS_FALLBACK_CALLER(FSIsEofAsync)
|
||||
DEFINE_FS_FALLBACK_CALLER(FSOpenFileAsync)
|
||||
DEFINE_FS_FALLBACK_CALLER(FSReadFileAsync)
|
||||
DEFINE_FS_FALLBACK_CALLER(FSReadFileWithPosAsync)
|
||||
DEFINE_FS_FALLBACK_CALLER(FSSetPosFileAsync)
|
53
plugins/sdcafiine/src/fs_wrapper/fs_wrapper_utils.h
Normal file
53
plugins/sdcafiine/src/fs_wrapper/fs_wrapper_utils.h
Normal file
@ -0,0 +1,53 @@
|
||||
/****************************************************************************
|
||||
* Copyright (C) 2017 Maschell
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __FS_WRAPPER_UTILS_H_
|
||||
#define __FS_WRAPPER_UTILS_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <dynamic_libs/fs_defs.h>
|
||||
#include <dynamic_libs/fs_functions.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int fallbackFSCloseFileAsync(void * fallbackparams);
|
||||
|
||||
int fallbackFSGetPosFileAsync(void * fallbackparams);
|
||||
|
||||
int fallbackFSGetStatAsync(void * fallbackparams);
|
||||
|
||||
int fallbackFSGetStatFileAsync(void * fallbackparams);
|
||||
|
||||
int fallbackFSFSGetPosFileAsync(void * fallbackparams);
|
||||
|
||||
int fallbackFSIsEofAsync(void * fallbackparams);
|
||||
|
||||
int fallbackFSOpenFileAsync(void * fallbackparams);
|
||||
|
||||
int fallbackFSReadFileAsync(void * fallbackparams);
|
||||
|
||||
int fallbackFSReadFileWithPosAsync(void * fallbackparams);
|
||||
|
||||
int fallbackFSSetPosFileAsync(void * fallbackparams);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __FS_WRAPPER_UTILS_H_
|
153
plugins/sdcafiine/src/main.cpp
Normal file
153
plugins/sdcafiine/src/main.cpp
Normal file
@ -0,0 +1,153 @@
|
||||
#include <wups.h>
|
||||
#include <string.h>
|
||||
#include <dynamic_libs/os_functions.h>
|
||||
#include <dynamic_libs/vpad_functions.h>
|
||||
#include <dynamic_libs/sys_functions.h>
|
||||
#include <dynamic_libs/proc_ui_functions.h>
|
||||
#include <dynamic_libs/socket_functions.h>
|
||||
#include <fs/sd_fat_devoptab.h>
|
||||
#include <fswrapper/FileReplacerUtils.h>
|
||||
#include <fswrapper/fs_default_os_wrapper.h>
|
||||
#include <utils/logger.h>
|
||||
#include "utils/fs_utils.h"
|
||||
#include "common/retain_vars.h"
|
||||
#include <iosuhax.h>
|
||||
#include "common/common.h"
|
||||
#include "main.h"
|
||||
|
||||
#define DEBUG_LOG 1
|
||||
|
||||
WUPS_MODULE_NAME("SDCaffiine");
|
||||
WUPS_MODULE_VERSION("v1.0");
|
||||
WUPS_MODULE_AUTHOR("Maschell");
|
||||
WUPS_MODULE_LICENSE("GPL");
|
||||
|
||||
static bool setGroupAndOwnerID();
|
||||
void Init_SD_USB();
|
||||
|
||||
INITIALIZE(){
|
||||
if(gAppStatus == 2){
|
||||
return;
|
||||
}
|
||||
InitOSFunctionPointers();
|
||||
InitSocketFunctionPointers(); //For logging
|
||||
|
||||
InitSysFunctionPointers(); // For SYSLaunchMenu()
|
||||
InitProcUIFunctionPointers(); // For SYSLaunchMenu()
|
||||
InitFSFunctionPointers();
|
||||
InitVPadFunctionPointers();
|
||||
|
||||
log_init();
|
||||
|
||||
gSDInitDone = 0;
|
||||
snprintf(gModFolder, FS_MAX_ENTNAME_SIZE, "sd:/sdcafiine/%016llX",OSGetTitleID());
|
||||
|
||||
DEBUG_FUNCTION_LINE("Folder: %s\n",gModFolder);
|
||||
DEBUG_FUNCTION_LINE("Mount SD partition\n");
|
||||
Init_SD_USB();
|
||||
|
||||
setGroupAndOwnerID();
|
||||
|
||||
g_dirhandles = vc_vector_create(0, sizeof(int), NULL);
|
||||
g_filehandles = vc_vector_create(0, sizeof(int), NULL);
|
||||
|
||||
log_print("Init of sd_cafiine!\n");
|
||||
}
|
||||
|
||||
|
||||
static bool setGroupAndOwnerID(){
|
||||
int mcpHandle = MCP_Open();
|
||||
if(mcpHandle != 0)
|
||||
{
|
||||
unsigned char titleInfo[0x80];
|
||||
memset(titleInfo, 0, sizeof(titleInfo));
|
||||
|
||||
MCP_GetOwnTitleInfo(mcpHandle, titleInfo);
|
||||
MCP_Close(mcpHandle);
|
||||
u32 * test = (u32*)titleInfo;
|
||||
global_owner_id = test[1];
|
||||
global_group_id = test[2];
|
||||
DEBUG_FUNCTION_LINE("Set group_id to %08X and owner_id to %08X\n",global_group_id,global_owner_id);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Init_SD_USB() {
|
||||
//int res = IOSUHAX_Open(NULL);
|
||||
//if(res < 0){
|
||||
//ExecuteIOSExploitWithDefaultConfig();
|
||||
// return;
|
||||
//}
|
||||
deleteDevTabsNames();
|
||||
mount_fake();
|
||||
gSDInitDone |= SDUSB_MOUNTED_FAKE;
|
||||
|
||||
int res = -1;
|
||||
if(res < 0){
|
||||
DEBUG_FUNCTION_LINE("IOSUHAX_open failed\n");
|
||||
if((res = mount_sd_fat("sd")) >= 0){
|
||||
DEBUG_FUNCTION_LINE("mount_sd_fat success\n");
|
||||
gSDInitDone |= SDUSB_MOUNTED_OS_SD;
|
||||
}else{
|
||||
DEBUG_FUNCTION_LINE("mount_sd_fat failed %d\n",res);
|
||||
}
|
||||
}else{
|
||||
DEBUG_FUNCTION_LINE("Using IOSUHAX for SD/USB access\n");
|
||||
gSDInitDone |= SDUSB_LIBIOSU_LOADED;
|
||||
int ntfs_mounts = 0; //mountAllNTFS();
|
||||
if(ntfs_mounts > 0){
|
||||
gSDInitDone |= USB_MOUNTED_LIBNTFS;
|
||||
}
|
||||
|
||||
/*if(mount_libfatAll() == 0){
|
||||
gSDInitDone |= SD_MOUNTED_LIBFAT;
|
||||
gSDInitDone |= USB_MOUNTED_LIBFAT;
|
||||
}*/
|
||||
}
|
||||
DEBUG_FUNCTION_LINE("%08X\n",gSDInitDone);
|
||||
}
|
||||
|
||||
void deInit_SD_USB(){
|
||||
DEBUG_FUNCTION_LINE("Called this function.\n");
|
||||
|
||||
if(gSDInitDone & SDUSB_MOUNTED_FAKE){
|
||||
DEBUG_FUNCTION_LINE("Unmounting fake\n");
|
||||
unmount_fake();
|
||||
gSDInitDone &= ~SDUSB_MOUNTED_FAKE;
|
||||
}
|
||||
if(gSDInitDone & SDUSB_MOUNTED_OS_SD){
|
||||
DEBUG_FUNCTION_LINE("Unmounting OS SD\n");
|
||||
unmount_sd_fat("sd");
|
||||
gSDInitDone &= ~SDUSB_MOUNTED_OS_SD;
|
||||
}
|
||||
|
||||
/*if(gSDInitDone & SD_MOUNTED_LIBFAT){
|
||||
DEBUG_FUNCTION_LINE("Unmounting LIBFAT SD\n");
|
||||
unmount_libfat("sd");
|
||||
gSDInitDone &= ~SD_MOUNTED_LIBFAT;
|
||||
}
|
||||
|
||||
if(gSDInitDone & USB_MOUNTED_LIBFAT){
|
||||
DEBUG_FUNCTION_LINE("Unmounting LIBFAT USB\n");
|
||||
unmount_libfat("usb");
|
||||
gSDInitDone &= ~USB_MOUNTED_LIBFAT;
|
||||
}
|
||||
|
||||
if(gSDInitDone & USB_MOUNTED_LIBNTFS){
|
||||
DEBUG_FUNCTION_LINE("Unmounting LIBNTFS USB\n");
|
||||
unmountAllNTFS();
|
||||
gSDInitDone &= ~USB_MOUNTED_LIBNTFS;
|
||||
}*/
|
||||
|
||||
if(gSDInitDone & SDUSB_LIBIOSU_LOADED){
|
||||
DEBUG_FUNCTION_LINE("Calling IOSUHAX_Close\n");
|
||||
IOSUHAX_Close();
|
||||
gSDInitDone &= ~SDUSB_LIBIOSU_LOADED;
|
||||
}
|
||||
deleteDevTabsNames();
|
||||
if(gSDInitDone != SDUSB_MOUNTED_NONE){
|
||||
DEBUG_FUNCTION_LINE("WARNING. Some devices are still mounted.\n");
|
||||
}
|
||||
DEBUG_FUNCTION_LINE("Function end.\n");
|
||||
}
|
18
plugins/sdcafiine/src/main.h
Normal file
18
plugins/sdcafiine/src/main.h
Normal file
@ -0,0 +1,18 @@
|
||||
#ifndef _MAIN_H_
|
||||
#define _MAIN_H_
|
||||
|
||||
#include <dynamic_libs/os_functions.h>
|
||||
#include <dynamic_libs/os_types.h>
|
||||
|
||||
/* Main */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void deInit_SD_USB();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
293
plugins/sdcafiine/src/patches.cpp
Normal file
293
plugins/sdcafiine/src/patches.cpp
Normal file
@ -0,0 +1,293 @@
|
||||
#include <wups.h>
|
||||
#include <string.h>
|
||||
#include <dynamic_libs/os_functions.h>
|
||||
#include <dynamic_libs/vpad_functions.h>
|
||||
#include <dynamic_libs/sys_functions.h>
|
||||
#include <dynamic_libs/proc_ui_functions.h>
|
||||
#include <dynamic_libs/socket_functions.h>
|
||||
#include <fswrapper/FileReplacerUtils.h>
|
||||
#include <fswrapper/fs_default_os_wrapper.h>
|
||||
#include <utils/logger.h>
|
||||
#include "utils/fs_utils.h"
|
||||
#include "common/retain_vars.h"
|
||||
#include "common/common.h"
|
||||
#include "main.h"
|
||||
|
||||
#define DEBUG_LOG 1
|
||||
|
||||
DECL_FUNCTION(void, __PPCExit, void){
|
||||
DEBUG_FUNCTION_LINE("__PPCExit\n");
|
||||
|
||||
deInit_SD_USB();
|
||||
|
||||
real___PPCExit();
|
||||
}
|
||||
|
||||
DECL_FUNCTION(u32, ProcUIProcessMessages, u32 u){
|
||||
u32 res = real_ProcUIProcessMessages(u);
|
||||
if(res != gAppStatus){
|
||||
DEBUG_FUNCTION_LINE("App status changed from %d to %d \n",gAppStatus,res);
|
||||
gAppStatus = res;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
DECL_FUNCTION(int, FSCloseFile, FSClient *pClient, FSCmdBlock *pCmd, int fd, int error) {
|
||||
if(gAppStatus == 2 || gSDInitDone <= SDUSB_MOUNTED_FAKE){ return real_FSCloseFile(pClient, pCmd, fd, error); }
|
||||
|
||||
int result = USE_OS_FS_FUNCTION;
|
||||
if((result = fs_wrapper_FSCloseFile(fd)) != USE_OS_FS_FUNCTION){
|
||||
return result;
|
||||
}
|
||||
|
||||
return real_FSCloseFile(pClient, pCmd, fd, setErrorFlag(error));
|
||||
}
|
||||
|
||||
DECL_FUNCTION(int, FSGetPosFile, FSClient *pClient, FSCmdBlock *pCmd, int fd, int *pos, int error) {
|
||||
if(gAppStatus == 2 || gSDInitDone <= SDUSB_MOUNTED_FAKE){ return real_FSGetPosFile(pClient, pCmd, fd, pos, error); }
|
||||
|
||||
int result = USE_OS_FS_FUNCTION;
|
||||
if((result = fs_wrapper_FSGetPosFile(fd,pos)) != USE_OS_FS_FUNCTION){
|
||||
return result;
|
||||
}
|
||||
|
||||
return real_FSGetPosFile(pClient, pCmd, fd, pos, setErrorFlag(error));
|
||||
}
|
||||
|
||||
DECL_FUNCTION(int, FSGetStat, FSClient *pClient, FSCmdBlock *pCmd, const char *path, FSStat *stats, int error) {
|
||||
if(gAppStatus == 2 || gSDInitDone <= SDUSB_MOUNTED_FAKE){ return real_FSGetStat(pClient, pCmd, path, stats, error); }
|
||||
|
||||
int result = USE_OS_FS_FUNCTION;
|
||||
|
||||
if(DEBUG_LOG){ DEBUG_FUNCTION_LINE("for path %s\n",path); }
|
||||
char * newPath = getPathWithNewBase(path,gModFolder);
|
||||
if(newPath != NULL){
|
||||
if((result = fs_wrapper_FSGetStat(newPath,stats)) != USE_OS_FS_FUNCTION){
|
||||
if(newPath){ free(newPath); newPath = NULL;}
|
||||
return result;
|
||||
}
|
||||
if(newPath){ free(newPath); newPath = NULL;} //Should be dead code...
|
||||
}
|
||||
|
||||
return real_FSGetStat(pClient, pCmd, path, stats, setErrorFlag(error));
|
||||
}
|
||||
|
||||
DECL_FUNCTION(int, FSGetStatFile, FSClient *pClient, FSCmdBlock *pCmd, int fd, FSStat * stats, int error) {
|
||||
if(gAppStatus == 2 || gSDInitDone <= SDUSB_MOUNTED_FAKE){ return real_FSGetStatFile(pClient, pCmd, fd, stats, error); }
|
||||
|
||||
int result = USE_OS_FS_FUNCTION;
|
||||
if((result = fs_wrapper_FSGetStatFile(fd,stats)) != USE_OS_FS_FUNCTION){
|
||||
return result;
|
||||
}
|
||||
|
||||
return real_FSGetStatFile(pClient, pCmd, fd, stats, setErrorFlag(error));
|
||||
}
|
||||
|
||||
DECL_FUNCTION(int, FSIsEof, FSClient *pClient, FSCmdBlock *pCmd, int fd, int error) {
|
||||
if(gAppStatus == 2 || gSDInitDone <= SDUSB_MOUNTED_FAKE) return real_FSIsEof(pClient, pCmd, fd, error);
|
||||
|
||||
int result = USE_OS_FS_FUNCTION;
|
||||
if((result = fs_wrapper_FSIsEof(fd)) != USE_OS_FS_FUNCTION){
|
||||
return result;
|
||||
}
|
||||
|
||||
return real_FSIsEof(pClient, pCmd, fd, setErrorFlag(error));
|
||||
}
|
||||
|
||||
DECL_FUNCTION(int, FSOpenFile, FSClient *pClient, FSCmdBlock *pCmd, const char *path, const char *mode, int *handle, int error) {
|
||||
if(gAppStatus == 2 || gSDInitDone <= SDUSB_MOUNTED_FAKE){ return real_FSOpenFile(pClient, pCmd, path, mode, handle, error); }
|
||||
|
||||
/*if(endsWith(path,BOOT_TV_TEX_TGA,-1,-1)){ //Mario Party 10 crashes when pressing the home button.
|
||||
if(startsWith("/vol/storage_mlc01/usr/title/",path)){
|
||||
u64 tID = getTitleIDFromPath(path);
|
||||
HandleMultiModPacks(tID,false);
|
||||
}else if(strlen(gLastMetaPath) > 0){
|
||||
DEBUG_FUNCTION_LINE("gLastMetaPath %s\n",gLastMetaPath);
|
||||
if(startsWith("/vol/storage_usb01/usr/title/",gLastMetaPath) ||
|
||||
startsWith("/vol/storage_mlc01/usr/title/",gLastMetaPath)
|
||||
){
|
||||
u64 tID = getTitleIDFromPath(gLastMetaPath);
|
||||
HandleMultiModPacks(tID,false);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
if(DEBUG_LOG){ DEBUG_FUNCTION_LINE("for path %s\n",path); }
|
||||
char * newPath = getPathWithNewBase(path,gModFolder);
|
||||
int result = USE_OS_FS_FUNCTION;
|
||||
|
||||
if(newPath != NULL){
|
||||
if((result = fs_wrapper_FSOpenFile(newPath,mode,handle)) != USE_OS_FS_FUNCTION){
|
||||
if(newPath){ free(newPath); newPath = NULL;}
|
||||
return result;
|
||||
}
|
||||
if(newPath){ free(newPath); newPath = NULL;} //Should be dead code...
|
||||
}
|
||||
|
||||
return real_FSOpenFile(pClient, pCmd, path, mode, handle, setErrorFlag(error));
|
||||
}
|
||||
|
||||
DECL_FUNCTION(int, FSReadFile, FSClient *pClient, FSCmdBlock *pCmd, void *buffer, int size, int count, int handle, int flag, int error) {
|
||||
if(gAppStatus == 2 || gSDInitDone <= SDUSB_MOUNTED_FAKE){ return real_FSReadFile(pClient, pCmd, buffer, size, count, handle, flag, error); }
|
||||
|
||||
int result = USE_OS_FS_FUNCTION;
|
||||
if((result = fs_wrapper_FSReadFile(handle,buffer,size,count)) != USE_OS_FS_FUNCTION){
|
||||
return result;
|
||||
}
|
||||
|
||||
return real_FSReadFile(pClient, pCmd, buffer, size, count, handle, flag, setErrorFlag(error));
|
||||
}
|
||||
|
||||
DECL_FUNCTION(int, FSSetPosFile, FSClient *pClient, FSCmdBlock *pCmd, int fd, u32 pos, int error) {
|
||||
if(gAppStatus == 2 || gSDInitDone <= SDUSB_MOUNTED_FAKE) return real_FSSetPosFile(pClient, pCmd, fd, pos, error);
|
||||
|
||||
int result = USE_OS_FS_FUNCTION;
|
||||
if((result = fs_wrapper_FSSetPosFile(fd,pos)) != USE_OS_FS_FUNCTION){
|
||||
return result;
|
||||
}
|
||||
|
||||
return real_FSSetPosFile(pClient, pCmd, fd, pos, setErrorFlag(error));
|
||||
}
|
||||
|
||||
DECL_FUNCTION(int, FSReadFileWithPos, FSClient *pClient, FSCmdBlock *pCmd, void *buffer, int size, int count, u32 pos, int fd, int flag, int error) {
|
||||
if(gAppStatus == 2 || gSDInitDone <= SDUSB_MOUNTED_FAKE){ return real_FSReadFileWithPos(pClient, pCmd, buffer, size, count, pos, fd, flag, error); }
|
||||
|
||||
int result = USE_OS_FS_FUNCTION;
|
||||
if((result = fs_wrapper_FSReadFileWithPos(buffer,size,count,pos,fd)) != USE_OS_FS_FUNCTION){
|
||||
return result;
|
||||
}
|
||||
|
||||
return real_FSReadFileWithPos(pClient, pCmd, buffer, size, count, pos, fd, flag, setErrorFlag(error));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
In theory it would be enough just to patch the "async" versions of the function.
|
||||
The non-async functions internally use the async function anyway.
|
||||
However this my be a bit faster/robust, when we handle the async functions async.
|
||||
**/
|
||||
|
||||
DECL_FUNCTION(int, FSCloseFileAsync, FSClient *pClient, FSCmdBlock *pCmd, int fd, int error, FSAsyncParams * asyncParams) {
|
||||
if(gAppStatus == 2 || checkErrorFlag(&error) || gSDInitDone <= SDUSB_MOUNTED_FAKE){ // Use the real implementation if the app is not in foreground or we already checked it.
|
||||
return real_FSCloseFileAsync(pClient, pCmd, fd, error, asyncParams);
|
||||
}
|
||||
|
||||
return fs_default_os_wrapper_FSCloseFileAsync(pClient, pCmd, fd, error, asyncParams,(void*) real_FSCloseFileAsync);
|
||||
}
|
||||
|
||||
DECL_FUNCTION(int, FSGetPosFileAsync, FSClient *pClient, FSCmdBlock *pCmd, int fd, int *pos, int error, FSAsyncParams * asyncParams) {
|
||||
if(gAppStatus == 2 || checkErrorFlag(&error) || gSDInitDone <= SDUSB_MOUNTED_FAKE){ // Use the real implementation if the app is not in foreground or we already checked it.
|
||||
return real_FSGetPosFileAsync(pClient, pCmd, fd, pos, error, asyncParams);
|
||||
}
|
||||
|
||||
return fs_default_os_wrapper_FSGetPosFileAsync(pClient, pCmd, fd, pos, error, asyncParams,(void*) real_FSGetPosFileAsync);
|
||||
}
|
||||
|
||||
DECL_FUNCTION(int, FSGetStatAsync, FSClient *pClient, FSCmdBlock *pCmd, const char *path, FSStat *stats, int error, FSAsyncParams * asyncParams) {
|
||||
if(gAppStatus == 2 || checkErrorFlag(&error) || gSDInitDone <= SDUSB_MOUNTED_FAKE){ // Use the real implementation if the app is not in foreground or we already checked it.
|
||||
return real_FSGetStatAsync(pClient, pCmd, path, stats, error, asyncParams);
|
||||
}
|
||||
|
||||
return fs_default_os_wrapper_FSGetStatAsync(getPathWithNewBase((char*)path,gModFolder),pClient, pCmd, path, stats, error, asyncParams,(void*) real_FSGetStatAsync);
|
||||
}
|
||||
|
||||
DECL_FUNCTION(int, FSGetStatFileAsync, FSClient *pClient, FSCmdBlock *pCmd, int fd, FSStat * stats, int error, FSAsyncParams * asyncParams) {
|
||||
if(gAppStatus == 2 || checkErrorFlag(&error) || gSDInitDone <= SDUSB_MOUNTED_FAKE){ // Use the real implementation if the app is not in foreground or we already checked it.
|
||||
return real_FSGetStatFileAsync(pClient, pCmd, fd, stats, error, asyncParams);
|
||||
}
|
||||
|
||||
return fs_default_os_wrapper_FSGetStatFileAsync(pClient, pCmd, fd, stats, error, asyncParams,(void*) real_FSGetStatFileAsync);
|
||||
}
|
||||
|
||||
DECL_FUNCTION(int, FSIsEofAsync, FSClient *pClient, FSCmdBlock *pCmd, int fd, int error, FSAsyncParams *asyncParams) {
|
||||
if(gAppStatus == 2 || checkErrorFlag(&error) || gSDInitDone <= SDUSB_MOUNTED_FAKE){ // Use the real implementation if the app is not in foreground or we already checked it.
|
||||
return real_FSIsEofAsync(pClient, pCmd, fd, error,asyncParams);
|
||||
}
|
||||
|
||||
return fs_default_os_wrapper_FSIsEofAsync(pClient, pCmd, fd, error,asyncParams,(void*) real_FSIsEofAsync);
|
||||
}
|
||||
/*
|
||||
u64 getTitleIDFromPath(const char * path){
|
||||
if(path == NULL || strlen(path) < 46) return 0;
|
||||
char titleID[0x11];
|
||||
char titleIDHigh[0x09];
|
||||
char titleIDLow[0x09];
|
||||
char * test = (char * )&path[29];
|
||||
snprintf(titleIDHigh,0x09,"%s",test);
|
||||
test = (char * ) &path[38];
|
||||
snprintf(titleIDLow,0x09,"%s",test);
|
||||
snprintf(titleID,0x11,"%s%s",titleIDHigh,titleIDLow);
|
||||
u64 tID = strtoll(titleID, NULL, 16);
|
||||
tID &= ~ 0x0000000E00000000; // remove update flag
|
||||
return tID;
|
||||
}*/
|
||||
|
||||
DECL_FUNCTION(int, FSOpenFileAsync, FSClient *pClient, FSCmdBlock *pCmd, const char *path, const char *mode, int *handle, int error, FSAsyncParams *asyncParams) {
|
||||
if(gAppStatus == 2 || checkErrorFlag(&error) || gSDInitDone <= SDUSB_MOUNTED_FAKE){ // Use the real implementation if the app is not in foreground or we already checked it.
|
||||
return real_FSOpenFileAsync(pClient, pCmd, path, mode, handle,error, asyncParams);
|
||||
}
|
||||
|
||||
return fs_default_os_wrapper_FSOpenFileAsync(getPathWithNewBase((char*)path,gModFolder), pClient, pCmd, path, mode, handle,error, asyncParams,(void*) real_FSOpenFileAsync);
|
||||
}
|
||||
|
||||
DECL_FUNCTION(int, FSReadFileAsync, FSClient *pClient, FSCmdBlock *pCmd, void *buffer, int size, int count, int fd, int flag, int error, FSAsyncParams *asyncParams) {
|
||||
if(gAppStatus == 2 || checkErrorFlag(&error) || gSDInitDone <= SDUSB_MOUNTED_FAKE){ // Use the real implementation if the app is not in foreground or we already checked it.
|
||||
return real_FSReadFileAsync(pClient, pCmd, buffer, size, count, fd, flag, error, asyncParams);
|
||||
}
|
||||
|
||||
return fs_default_os_wrapper_FSReadFileAsync(pClient, pCmd, buffer, size, count, fd, flag, error, asyncParams, (void*) real_FSReadFileAsync);
|
||||
}
|
||||
|
||||
DECL_FUNCTION(int, FSReadFileWithPosAsync, FSClient *pClient, FSCmdBlock *pCmd, void *buffer, int size, int count, u32 pos, int fd, int flag, int error, FSAsyncParams *asyncParams) {
|
||||
if(gAppStatus == 2 || checkErrorFlag(&error) || gSDInitDone <= SDUSB_MOUNTED_FAKE){ // Use the real implementation if the app is not in foreground or we already checked it.
|
||||
return real_FSReadFileWithPosAsync(pClient, pCmd, buffer, size, count, pos, fd, flag, error, asyncParams);
|
||||
}
|
||||
|
||||
return fs_default_os_wrapper_FSReadFileWithPosAsync(pClient, pCmd, buffer, size, count, pos, fd, flag, error, asyncParams, (void*) real_FSReadFileWithPosAsync);
|
||||
}
|
||||
|
||||
DECL_FUNCTION(int, FSSetPosFileAsync, FSClient *pClient, FSCmdBlock *pCmd, int handle, u32 pos, int error, FSAsyncParams *asyncParams) {
|
||||
if(gAppStatus == 2 || checkErrorFlag(&error) || gSDInitDone <= SDUSB_MOUNTED_FAKE){ // Use the real implementation if the app is not in foreground or we already checked it.
|
||||
return real_FSSetPosFileAsync(pClient, pCmd, handle, pos, error,asyncParams);
|
||||
}
|
||||
|
||||
return fs_default_os_wrapper_FSSetPosFileAsync(pClient, pCmd, handle, pos, error,asyncParams, (void*) real_FSSetPosFileAsync);
|
||||
}
|
||||
|
||||
/*
|
||||
DECL_FUNCTION(int, FSBindMount, void *pClient, void *pCmd, char *source, char *target, int error){
|
||||
if(gAppStatus == 2) return real_FSBindMount(pClient,pCmd,source,target,error);
|
||||
memcpy(gLastMetaPath,source,strlen(source) + 1);
|
||||
return real_FSBindMount(pClient,pCmd,source,target,error);
|
||||
}
|
||||
DECL_FUNCTION(int, FSBindUnmount, void *pClient, void *pCmd, char *target, int error){
|
||||
if(gAppStatus == 2) real_FSBindUnmount(pClient,pCmd,target,error);
|
||||
gLastMetaPath[0] = 0;
|
||||
return real_FSBindUnmount(pClient,pCmd,target,error);
|
||||
}*/
|
||||
|
||||
|
||||
WUPS_MUST_REPLACE(FSCloseFile, WUPS_LOADER_LIBRARY_COREINIT, FSCloseFile);
|
||||
WUPS_MUST_REPLACE(FSGetPosFile, WUPS_LOADER_LIBRARY_COREINIT, FSGetPosFile);
|
||||
WUPS_MUST_REPLACE(FSGetStat, WUPS_LOADER_LIBRARY_COREINIT, FSGetStat);
|
||||
WUPS_MUST_REPLACE(FSGetStatFile, WUPS_LOADER_LIBRARY_COREINIT, FSGetStatFile);
|
||||
WUPS_MUST_REPLACE(FSIsEof, WUPS_LOADER_LIBRARY_COREINIT, FSIsEof);
|
||||
WUPS_MUST_REPLACE(FSOpenFile, WUPS_LOADER_LIBRARY_COREINIT, FSOpenFile);
|
||||
WUPS_MUST_REPLACE(FSReadFile, WUPS_LOADER_LIBRARY_COREINIT, FSReadFile);
|
||||
WUPS_MUST_REPLACE(FSReadFileWithPos, WUPS_LOADER_LIBRARY_COREINIT, FSReadFileWithPos);
|
||||
WUPS_MUST_REPLACE(FSSetPosFile, WUPS_LOADER_LIBRARY_COREINIT, FSSetPosFile);
|
||||
|
||||
WUPS_MUST_REPLACE(FSCloseFileAsync, WUPS_LOADER_LIBRARY_COREINIT, FSCloseFileAsync);
|
||||
WUPS_MUST_REPLACE(FSGetPosFileAsync, WUPS_LOADER_LIBRARY_COREINIT, FSGetPosFileAsync);
|
||||
WUPS_MUST_REPLACE(FSGetStatAsync, WUPS_LOADER_LIBRARY_COREINIT, FSGetStatAsync);
|
||||
WUPS_MUST_REPLACE(FSGetStatFileAsync, WUPS_LOADER_LIBRARY_COREINIT, FSGetStatFileAsync);
|
||||
WUPS_MUST_REPLACE(FSIsEofAsync, WUPS_LOADER_LIBRARY_COREINIT, FSIsEofAsync);
|
||||
WUPS_MUST_REPLACE(FSOpenFileAsync, WUPS_LOADER_LIBRARY_COREINIT, FSOpenFileAsync);
|
||||
WUPS_MUST_REPLACE(FSReadFileAsync, WUPS_LOADER_LIBRARY_COREINIT, FSReadFileAsync);
|
||||
WUPS_MUST_REPLACE(FSReadFileWithPosAsync, WUPS_LOADER_LIBRARY_COREINIT, FSReadFileWithPosAsync);
|
||||
WUPS_MUST_REPLACE(FSSetPosFileAsync, WUPS_LOADER_LIBRARY_COREINIT, FSSetPosFileAsync);
|
||||
|
||||
|
||||
WUPS_MUST_REPLACE(__PPCExit, WUPS_LOADER_LIBRARY_COREINIT, __PPCExit);
|
||||
WUPS_MUST_REPLACE(ProcUIProcessMessages, WUPS_LOADER_LIBRARY_PROC_UI, ProcUIProcessMessages);
|
147
plugins/sdcafiine/src/utils/fs_utils.cpp
Normal file
147
plugins/sdcafiine/src/utils/fs_utils.cpp
Normal file
@ -0,0 +1,147 @@
|
||||
#include <malloc.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <utils/logger.h>
|
||||
#include <utils/StringTools.h>
|
||||
|
||||
#include "fs_utils.h"
|
||||
#include "common/common.h"
|
||||
#include "common/retain_vars.h"
|
||||
|
||||
int is_gamefile(const char *path) {
|
||||
if(path == NULL) return 0;
|
||||
if(strncmp(path,"CAFE/",5) == 0) return GAME_PATH_TYPE_STRIPPED_CONTENT; //Workaround for NSMBU
|
||||
|
||||
// In case the path starts by "//" and not "/" (some games do that ... ...)
|
||||
if (path[0] == '/' && path[1] == '/')
|
||||
path = &path[1];
|
||||
|
||||
// In case the path does not start with "/" (some games do that too ...)
|
||||
int len = 0;
|
||||
char new_path[16];
|
||||
if(path[0] != '/') {
|
||||
new_path[0] = '/';
|
||||
len++;
|
||||
}
|
||||
|
||||
while(*path && len < (int)(sizeof(new_path) - 1)) {
|
||||
new_path[len++] = *path++;
|
||||
}
|
||||
new_path[len++] = 0;
|
||||
|
||||
if(strncmp(new_path,"/vol/content",12) == 0) return GAME_PATH_TYPE_CONTENT;
|
||||
//dlc support
|
||||
if(strncmp(new_path,"/vol/aoc",8) == 0) return GAME_PATH_TYPE_AOC;
|
||||
|
||||
return 0;
|
||||
}
|
||||
char * getPathWithNewBase(const char * inPath, const char * newBase){
|
||||
if(inPath == NULL || *inPath == 0 || newBase == NULL || *newBase == 0) return NULL;
|
||||
char * relativePath = getRelativePath(inPath);
|
||||
char * result = NULL;
|
||||
|
||||
if(relativePath == NULL){
|
||||
/*
|
||||
if(strlen(gModFolder) > 0){
|
||||
int file = 0;
|
||||
if(endsWith(inPath,BOOT_TV_TEX_TGA,-1,-1)){ file = 1;}
|
||||
else if(endsWith(inPath,BOOT_DRC_TEX_TGA,-1,-1)){ file = 2;}
|
||||
else if(endsWith(inPath,BOOT_SOUND_BTSND,-1,-1)){ file = 3;}
|
||||
if(file == 0){ return NULL;}
|
||||
|
||||
result = (char*)malloc((sizeof(char) * (strlen(newBase) +1 + strlen(META_FOLDER) + 1 + 20) + 1));
|
||||
if(result == NULL){
|
||||
DEBUG_FUNCTION_LINE("malloc for result failed.\n");
|
||||
return NULL;
|
||||
}
|
||||
if(file == 1){sprintf(result,"%s/%s/%s",newBase,META_FOLDER,BOOT_TV_TEX_TGA);}
|
||||
if(file == 2){sprintf(result,"%s/%s/%s",newBase,META_FOLDER,BOOT_DRC_TEX_TGA);}
|
||||
if(file == 3){sprintf(result,"%s/%s/%s",newBase,META_FOLDER,BOOT_SOUND_BTSND);}
|
||||
return result;
|
||||
}*/
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
result = (char*)malloc((sizeof(char) * (strlen(newBase) +1+ strlen(relativePath))) + 1);
|
||||
if(result == NULL){
|
||||
DEBUG_FUNCTION_LINE("malloc for result failed.\n");
|
||||
OSFATAL_FUNCTION_LINE("malloc for result failed.\n");
|
||||
return NULL;
|
||||
}
|
||||
sprintf(result,"%s/%s",newBase,relativePath);
|
||||
|
||||
free(relativePath);
|
||||
relativePath = NULL;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
char * getRelativePath(const char *path){
|
||||
if(path == NULL) return NULL;
|
||||
char * pathForCheck = NULL;
|
||||
|
||||
int gameFile = is_gamefile(path);
|
||||
if(gameFile > 0) {
|
||||
//if(DEBUG_LOG) log_printf("getNewPath %s\n", path);
|
||||
int path_offset = 0;
|
||||
|
||||
// In case the path starts by "//" and not "/" (some games do that ... ...)
|
||||
if (path[0] == '/' && path[1] == '/')
|
||||
path = &path[1];
|
||||
|
||||
// In case the path does not start with "/" set an offset for all the accesses
|
||||
if(path[0] != '/')
|
||||
path_offset = -1;
|
||||
|
||||
|
||||
if(gameFile == GAME_PATH_TYPE_CONTENT) { // is content
|
||||
//content
|
||||
|
||||
// some games are doing /vol/content/./....
|
||||
if(path[13 + path_offset] == '.' && path[14 + path_offset] == '/') {
|
||||
path_offset += 2;
|
||||
}
|
||||
char * pathForCheckInternal = (char*)path + 13 + path_offset;
|
||||
if(pathForCheckInternal[0] == '/') pathForCheckInternal++; //Skip double slash
|
||||
|
||||
pathForCheck = (char*)malloc(sizeof(CONTENT_FOLDER) + 1 + (sizeof(char) * (strlen(pathForCheckInternal) + 1)));
|
||||
if(pathForCheck == NULL){
|
||||
DEBUG_FUNCTION_LINE("malloc failed\n");
|
||||
OSFATAL_FUNCTION_LINE("malloc failed\n");
|
||||
return NULL;
|
||||
}
|
||||
sprintf(pathForCheck,"%s/%s",CONTENT_FOLDER,pathForCheckInternal);
|
||||
} else if (gameFile == GAME_PATH_TYPE_AOC) { // is aoc
|
||||
//aoc
|
||||
int aocFolderLength = 1;
|
||||
char * aocFolderLengthCheck = (char*)path + 5 + path_offset;
|
||||
while (aocFolderLengthCheck[0] != '/') {
|
||||
aocFolderLength++;
|
||||
aocFolderLengthCheck++;
|
||||
}
|
||||
char * pathForCheckInternal = (char*)path + 5 + aocFolderLength + path_offset;
|
||||
if(pathForCheckInternal[0] == '/') pathForCheckInternal++; //Skip double slash
|
||||
|
||||
pathForCheck = (char*)malloc(sizeof(AOC_FOLDER) + 1 + (sizeof(char) * (strlen(pathForCheckInternal) + 1)));
|
||||
if(pathForCheck == NULL){
|
||||
DEBUG_FUNCTION_LINE("malloc failed\n");
|
||||
OSFATAL_FUNCTION_LINE("malloc failed\n");
|
||||
return NULL;
|
||||
}
|
||||
sprintf(pathForCheck,"%s/%s",AOC_FOLDER,pathForCheckInternal);
|
||||
} else if (gameFile == GAME_PATH_TYPE_STRIPPED_CONTENT) { // is stripped content
|
||||
pathForCheck = (char*)malloc(sizeof(CONTENT_FOLDER) + 1 + (sizeof(char) * (strlen(path) + 1)));
|
||||
if(pathForCheck == NULL){
|
||||
DEBUG_FUNCTION_LINE("malloc failed\n");
|
||||
OSFATAL_FUNCTION_LINE("malloc failed\n");
|
||||
return NULL;
|
||||
}
|
||||
sprintf(pathForCheck,"%s/%s",CONTENT_FOLDER,path);
|
||||
}
|
||||
}
|
||||
|
||||
return pathForCheck;
|
||||
}
|
18
plugins/sdcafiine/src/utils/fs_utils.h
Normal file
18
plugins/sdcafiine/src/utils/fs_utils.h
Normal file
@ -0,0 +1,18 @@
|
||||
#ifndef __SDCAFIINE_FS_UTILS_H_
|
||||
#define __SDCAFIINE_FS_UTILS_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <dynamic_libs/os_types.h>
|
||||
|
||||
int is_gamefile(const char *path);
|
||||
char * getPathWithNewBase(const char * inPath, const char * newBase);
|
||||
char * getRelativePath(const char *path);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __FS_UTILS_H_
|
329
plugins/sdcafiine/src/utils/vc_vector.c
Normal file
329
plugins/sdcafiine/src/utils/vc_vector.c
Normal file
@ -0,0 +1,329 @@
|
||||
#include "vc_vector.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define GROWTH_FACTOR 1.5
|
||||
#define DEFAULT_COUNT_OF_ELEMENETS 8
|
||||
#define MINIMUM_COUNT_OF_ELEMENTS 2
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// vc_vector structure
|
||||
|
||||
struct vc_vector {
|
||||
size_t count;
|
||||
size_t element_size;
|
||||
size_t reserved_size;
|
||||
char* data;
|
||||
vc_vector_deleter* deleter;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// auxillary methods
|
||||
|
||||
bool vc_vector_realloc(vc_vector* vector, size_t new_count) {
|
||||
const size_t new_size = new_count * vector->element_size;
|
||||
char* new_data = (char*)realloc(vector->data, new_size);
|
||||
if (!new_data) {
|
||||
return false;
|
||||
}
|
||||
|
||||
vector->reserved_size = new_size;
|
||||
vector->data = new_data;
|
||||
return true;
|
||||
}
|
||||
|
||||
// [first_index, last_index)
|
||||
void vc_vector_call_deleter(vc_vector* vector, size_t first_index, size_t last_index) {
|
||||
for (size_t i = first_index; i < last_index; ++i) {
|
||||
vector->deleter(vc_vector_at(vector, i));
|
||||
}
|
||||
}
|
||||
|
||||
void vc_vector_call_deleter_all(vc_vector* vector) {
|
||||
vc_vector_call_deleter(vector, 0, vc_vector_count(vector));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Contol
|
||||
|
||||
vc_vector* vc_vector_create(size_t count_elements, size_t size_of_element, vc_vector_deleter* deleter) {
|
||||
vc_vector* v = (vc_vector*)malloc(sizeof(vc_vector));
|
||||
if (v != NULL) {
|
||||
v->data = NULL;
|
||||
v->count = 0;
|
||||
v->element_size = size_of_element;
|
||||
v->deleter = deleter;
|
||||
|
||||
if (count_elements < MINIMUM_COUNT_OF_ELEMENTS) {
|
||||
count_elements = DEFAULT_COUNT_OF_ELEMENETS;
|
||||
}
|
||||
|
||||
if (size_of_element < 1 ||
|
||||
!vc_vector_realloc(v, count_elements)) {
|
||||
free(v);
|
||||
v = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
vc_vector* vc_vector_create_copy(const vc_vector* vector) {
|
||||
vc_vector* new_vector = vc_vector_create(vector->reserved_size / vector->count,
|
||||
vector->element_size,
|
||||
vector->deleter);
|
||||
if (!new_vector) {
|
||||
return new_vector;
|
||||
}
|
||||
|
||||
if (memcpy(vector->data,
|
||||
new_vector->data,
|
||||
new_vector->element_size * vector->count) == NULL) {
|
||||
vc_vector_release(new_vector);
|
||||
new_vector = NULL;
|
||||
return new_vector;
|
||||
}
|
||||
|
||||
new_vector->count = vector->count;
|
||||
return new_vector;
|
||||
}
|
||||
|
||||
void vc_vector_release(vc_vector* vector) {
|
||||
if (vector->deleter != NULL) {
|
||||
vc_vector_call_deleter_all(vector);
|
||||
}
|
||||
|
||||
if (vector->reserved_size != 0) {
|
||||
free(vector->data);
|
||||
}
|
||||
|
||||
free(vector);
|
||||
}
|
||||
|
||||
bool vc_vector_is_equals(vc_vector* vector1, vc_vector* vector2) {
|
||||
const size_t size_vector1 = vc_vector_size(vector1);
|
||||
if (size_vector1 != vc_vector_size(vector2)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return memcmp(vector1->data, vector2->data, size_vector1) == 0;
|
||||
}
|
||||
|
||||
float vc_vector_get_growth_factor() {
|
||||
return GROWTH_FACTOR;
|
||||
}
|
||||
|
||||
size_t vc_vector_get_default_count_of_elements() {
|
||||
return DEFAULT_COUNT_OF_ELEMENETS;
|
||||
}
|
||||
|
||||
size_t vc_vector_struct_size() {
|
||||
return sizeof(vc_vector);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Element access
|
||||
|
||||
void* vc_vector_at(vc_vector* vector, size_t index) {
|
||||
return vector->data + index * vector->element_size;
|
||||
}
|
||||
|
||||
void* vc_vector_front(vc_vector* vector) {
|
||||
return vector->data;
|
||||
}
|
||||
|
||||
void* vc_vector_back(vc_vector* vector) {
|
||||
return vector->data + (vector->count - 1) * vector->element_size;
|
||||
}
|
||||
|
||||
void* vc_vector_data(vc_vector* vector) {
|
||||
return vector->data;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Iterators
|
||||
|
||||
void* vc_vector_begin(vc_vector* vector) {
|
||||
return vector->data;
|
||||
}
|
||||
|
||||
void* vc_vector_end(vc_vector* vector) {
|
||||
return vector->data + vector->element_size * vector->count;
|
||||
}
|
||||
|
||||
void* vc_vector_next(vc_vector* vector, void* i) {
|
||||
return i + vector->element_size;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Capacity
|
||||
|
||||
bool vc_vector_empty(vc_vector* vector) {
|
||||
return vector->count == 0;
|
||||
}
|
||||
|
||||
size_t vc_vector_count(const vc_vector* vector) {
|
||||
return vector->count;
|
||||
}
|
||||
|
||||
size_t vc_vector_size(const vc_vector* vector) {
|
||||
return vector->count * vector->element_size;
|
||||
}
|
||||
|
||||
size_t vc_vector_max_count(const vc_vector* vector) {
|
||||
return vector->reserved_size / vector->element_size;
|
||||
}
|
||||
|
||||
size_t vc_vector_max_size(const vc_vector* vector) {
|
||||
return vector->reserved_size;
|
||||
}
|
||||
|
||||
bool vc_vector_reserve_count(vc_vector* vector, size_t new_count) {
|
||||
if (new_count < vector->count) {
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t new_size = vector->element_size * new_count;
|
||||
if (new_size == vector->reserved_size) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return vc_vector_realloc(vector, new_count);
|
||||
}
|
||||
|
||||
bool vc_vector_reserve_size(vc_vector* vector, size_t new_size) {
|
||||
return vc_vector_reserve_count(vector, new_size / vector->element_size);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Modifiers
|
||||
|
||||
void vc_vector_clear(vc_vector* vector) {
|
||||
if (vector->deleter != NULL) {
|
||||
vc_vector_call_deleter_all(vector);
|
||||
}
|
||||
|
||||
vector->count = 0;
|
||||
}
|
||||
|
||||
bool vc_vector_insert(vc_vector* vector, size_t index, const void* value) {
|
||||
if (vc_vector_max_count(vector) < vector->count + 1) {
|
||||
if (!vc_vector_realloc(vector, vc_vector_max_count(vector) * GROWTH_FACTOR)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!memmove(vc_vector_at(vector, index + 1),
|
||||
vc_vector_at(vector, index),
|
||||
vector->element_size * (vector->count - index))) {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (memcpy(vc_vector_at(vector, index),
|
||||
value,
|
||||
vector->element_size) == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
++vector->count;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool vc_vector_erase(vc_vector* vector, size_t index) {
|
||||
if (vector->deleter != NULL) {
|
||||
vector->deleter(vc_vector_at(vector, index));
|
||||
}
|
||||
|
||||
if (!memmove(vc_vector_at(vector, index),
|
||||
vc_vector_at(vector, index + 1),
|
||||
vector->element_size * (vector->count - index))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
vector->count--;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool vc_vector_erase_range(vc_vector* vector, size_t first_index, size_t last_index) {
|
||||
if (vector->deleter != NULL) {
|
||||
vc_vector_call_deleter(vector, first_index, last_index);
|
||||
}
|
||||
|
||||
if (!memmove(vc_vector_at(vector, first_index),
|
||||
vc_vector_at(vector, last_index),
|
||||
vector->element_size * (vector->count - last_index))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
vector->count -= last_index - first_index;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool vc_vector_append(vc_vector* vector, const void* values, size_t count) {
|
||||
const size_t count_new = count + vc_vector_count(vector);
|
||||
|
||||
if (vc_vector_max_count(vector) < count_new) {
|
||||
size_t max_count_to_reserved = vc_vector_max_count(vector) * GROWTH_FACTOR;
|
||||
while (count_new > max_count_to_reserved) {
|
||||
max_count_to_reserved *= GROWTH_FACTOR;
|
||||
}
|
||||
|
||||
if (!vc_vector_realloc(vector, max_count_to_reserved)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (memcpy(vector->data + vector->count * vector->element_size,
|
||||
values,
|
||||
vector->element_size * count) == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
vector->count = count_new;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool vc_vector_push_back(vc_vector* vector, const void* value) {
|
||||
if (!vc_vector_append(vector, value, 1)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool vc_vector_pop_back(vc_vector* vector) {
|
||||
if (vector->deleter != NULL) {
|
||||
vector->deleter(vc_vector_back(vector));
|
||||
}
|
||||
|
||||
vector->count--;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool vc_vector_replace(vc_vector* vector, size_t index, const void* value) {
|
||||
if (vector->deleter != NULL) {
|
||||
vector->deleter(vc_vector_at(vector, index));
|
||||
}
|
||||
|
||||
return memcpy(vc_vector_at(vector, index),
|
||||
value,
|
||||
vector->element_size) != NULL;
|
||||
}
|
||||
|
||||
bool vc_vector_replace_multiple(vc_vector* vector, size_t index, const void* values, size_t count) {
|
||||
if (vector->deleter != NULL) {
|
||||
vc_vector_call_deleter(vector, index, index + count);
|
||||
}
|
||||
|
||||
return memcpy(vc_vector_at(vector, index),
|
||||
values,
|
||||
vector->element_size * count) != NULL;
|
||||
}
|
130
plugins/sdcafiine/src/utils/vc_vector.h
Normal file
130
plugins/sdcafiine/src/utils/vc_vector.h
Normal file
@ -0,0 +1,130 @@
|
||||
#ifndef VCVECTOR_H
|
||||
#define VCVECTOR_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct vc_vector vc_vector;
|
||||
typedef void (vc_vector_deleter)(void *);
|
||||
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Control
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Constructs an empty vector with an reserver size for count_elements.
|
||||
vc_vector* vc_vector_create(size_t count_elements, size_t size_of_element, vc_vector_deleter* deleter);
|
||||
|
||||
// Constructs a copy of an existing vector.
|
||||
vc_vector* vc_vector_create_copy(const vc_vector* vector);
|
||||
|
||||
// Releases the vector.
|
||||
void vc_vector_release(vc_vector* vector);
|
||||
|
||||
// Compares vector content
|
||||
bool vc_vector_is_equals(vc_vector* vector1, vc_vector* vector2);
|
||||
|
||||
// Returns constant value of the vector growth factor.
|
||||
float vc_vector_get_growth_factor();
|
||||
|
||||
// Returns constant value of the vector default count of elements.
|
||||
size_t vc_vector_get_default_count_of_elements();
|
||||
|
||||
// Returns constant value of the vector struct size.
|
||||
size_t vc_vector_struct_size();
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Element access
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Returns the item at index position in the vector.
|
||||
void* vc_vector_at(vc_vector* vector, size_t index);
|
||||
|
||||
// Returns the first item in the vector.
|
||||
void* vc_vector_front(vc_vector* vector);
|
||||
|
||||
// Returns the last item in the vector.
|
||||
void* vc_vector_back(vc_vector* vector);
|
||||
|
||||
// Returns a pointer to the data stored in the vector. The pointer can be used to access and modify the items in the vector.
|
||||
void* vc_vector_data(vc_vector* vector);
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Iterators
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Returns a pointer to the first item in the vector.
|
||||
void* vc_vector_begin(vc_vector* vector);
|
||||
|
||||
// Returns a pointer to the imaginary item after the last item in the vector.
|
||||
void* vc_vector_end(vc_vector* vector);
|
||||
|
||||
// Returns a pointer to the next element of vector after 'i'.
|
||||
void* vc_vector_next(vc_vector* vector, void* i);
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Capacity
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Returns true if the vector is empty; otherwise returns false.
|
||||
bool vc_vector_empty(vc_vector* vector);
|
||||
|
||||
// Returns the number of elements in the vector.
|
||||
size_t vc_vector_count(const vc_vector* vector);
|
||||
|
||||
// Returns the size (in bytes) of occurrences of value in the vector.
|
||||
size_t vc_vector_size(const vc_vector* vector);
|
||||
|
||||
// Returns the maximum number of elements that the vector can hold.
|
||||
size_t vc_vector_max_count(const vc_vector* vector);
|
||||
|
||||
// Returns the maximum size (in bytes) that the vector can hold.
|
||||
size_t vc_vector_max_size(const vc_vector* vector);
|
||||
|
||||
// Resizes the container so that it contains n elements.
|
||||
bool vc_vector_reserve_count(vc_vector* vector, size_t new_count);
|
||||
|
||||
// Resizes the container so that it contains new_size / element_size elements.
|
||||
bool vc_vector_reserve_size(vc_vector* vector, size_t new_size);
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Modifiers
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Removes all elements from the vector (without reallocation).
|
||||
void vc_vector_clear(vc_vector* vector);
|
||||
|
||||
// The container is extended by inserting a new element at position.
|
||||
bool vc_vector_insert(vc_vector* vector, size_t index, const void* value);
|
||||
|
||||
// Removes from the vector a single element by 'index'
|
||||
bool vc_vector_erase(vc_vector* vector, size_t index);
|
||||
|
||||
// Removes from the vector a range of elements '[first_index, last_index)'.
|
||||
bool vc_vector_erase_range(vc_vector* vector, size_t first_index, size_t last_index);
|
||||
|
||||
// Inserts multiple values at the end of the vector.
|
||||
bool vc_vector_append(vc_vector* vector, const void* values, size_t count);
|
||||
|
||||
// Inserts value at the end of the vector.
|
||||
bool vc_vector_push_back(vc_vector* vector, const void* value);
|
||||
|
||||
// Removes the last item in the vector.
|
||||
bool vc_vector_pop_back(vc_vector* vector);
|
||||
|
||||
// Replace value by index in the vector.
|
||||
bool vc_vector_replace(vc_vector* vector, size_t index, const void* value);
|
||||
|
||||
// Replace multiple values by index in the vector.
|
||||
bool vc_vector_replace_multiple(vc_vector* vector, size_t index, const void* values, size_t count);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // VCVECTOR_H
|
Loading…
Reference in New Issue
Block a user