[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:
Maschell 2018-02-11 18:33:07 +01:00
parent 2cbc49b030
commit ac912010f2
25 changed files with 2795 additions and 0 deletions

View File

@ -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
View 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
#---------------------------------------------------------------------------------

View 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>

View 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 */

View 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;

View 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_

View 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;
}

View 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_

View 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)

View 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_

View 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(&paramWrapper,0,sizeof(FallbackParamWrapper));
CustomAsyncParam params;
memset(&params,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,&paramWrapper);
}
int fs_default_os_wrapper_FSGetPosFileAsync(FSClient *pClient, FSCmdBlock *pCmd, int fd, int *pos, int error, FSAsyncParams * asyncParams, void * realAddress){
FallbackParamWrapper paramWrapper;
memset(&paramWrapper,0,sizeof(FallbackParamWrapper));
CustomAsyncParam params;
memset(&params,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,&paramWrapper);
}
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(&paramWrapper,0,sizeof(FallbackParamWrapper));
CustomAsyncParam params;
memset(&params,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,&paramWrapper);
}
int fs_default_os_wrapper_FSGetStatFileAsync(FSClient *pClient, FSCmdBlock *pCmd, int fd, FSStat * stats, int error, FSAsyncParams * asyncParams, void * realAddress){
FallbackParamWrapper paramWrapper;
memset(&paramWrapper,0,sizeof(FallbackParamWrapper));
CustomAsyncParam params;
memset(&params,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,&paramWrapper);
}
int fs_default_os_wrapper_FSIsEofAsync(FSClient *pClient, FSCmdBlock *pCmd, int fd, int error, FSAsyncParams * asyncParams, void * realAddress){
FallbackParamWrapper paramWrapper;
memset(&paramWrapper,0,sizeof(FallbackParamWrapper));
CustomAsyncParam params;
memset(&params,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,&paramWrapper);
}
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(&paramWrapper,0,sizeof(FallbackParamWrapper));
CustomAsyncParam params;
memset(&params,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,&paramWrapper);
}
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(&paramWrapper,0,sizeof(FallbackParamWrapper));
CustomAsyncParam params;
memset(&params,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,&paramWrapper);
}
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(&paramWrapper,0,sizeof(FallbackParamWrapper));
CustomAsyncParam params;
memset(&params,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,&paramWrapper);
}
int fs_default_os_wrapper_FSSetPosFileAsync(FSClient *pClient, FSCmdBlock *pCmd, int handle, u32 pos, int error, FSAsyncParams *asyncParams, void * realAddress){
FallbackParamWrapper paramWrapper;
memset(&paramWrapper,0,sizeof(FallbackParamWrapper));
CustomAsyncParam params;
memset(&params,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,&paramWrapper);
}

View 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_

View 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;

View 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_

View 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;
}

View 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_

View 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)

View 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_

View 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");
}

View 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

View 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);

View 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;
}

View 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_

View 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;
}

View 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