mirror of
https://github.com/libretro/RetroArch
synced 2025-04-07 13:23:32 +00:00
Merge pull request #12673 from QuarkTheAwesome/filesystem-opt
(Wii U) Filesystem optimisations
This commit is contained in:
commit
80fc5062c1
@ -2377,10 +2377,10 @@ endif
|
||||
|
||||
ifeq ($(WANT_IOSUHAX), 1)
|
||||
DEFINES += -DHAVE_IOSUHAX
|
||||
INCLUDE_DIRS += -I$(DEPS_DIR)/libiosuhax
|
||||
OBJ += $(DEPS_DIR)/libiosuhax/iosuhax.o \
|
||||
$(DEPS_DIR)/libiosuhax/iosuhax_devoptab.o \
|
||||
$(DEPS_DIR)/libiosuhax/iosuhax_disc_interface.o
|
||||
INCLUDE_DIRS += -I$(DEPS_DIR)/libiosuhax/include
|
||||
OBJ += $(DEPS_DIR)/libiosuhax/source/iosuhax.o \
|
||||
$(DEPS_DIR)/libiosuhax/source/iosuhax_devoptab.o \
|
||||
$(DEPS_DIR)/libiosuhax/source/iosuhax_disc_interface.o
|
||||
endif
|
||||
|
||||
ifeq ($(WANT_LIBFAT), 1)
|
||||
|
@ -102,7 +102,7 @@ endif
|
||||
|
||||
INCDIRS += -Ilibretro-common/include/compat/zlib
|
||||
# for stb, libfat, iosuhax
|
||||
INCDIRS += -Ideps -Ideps/libfat/include -Ideps/libiosuhax
|
||||
INCDIRS += -Ideps -Ideps/libfat/include -Ideps/libiosuhax/include
|
||||
# pad_functions uses wiiu/input.h
|
||||
INCDIRS += -Iinput/include
|
||||
INCDIRS += -Ideps/SPIRV-Cross
|
||||
|
4
deps/libfat/common.h
vendored
4
deps/libfat/common.h
vendored
@ -63,8 +63,8 @@
|
||||
|
||||
/* Platform specific options */
|
||||
#if defined (__wiiu__)
|
||||
#define DEFAULT_CACHE_PAGES 4
|
||||
#define DEFAULT_SECTORS_PAGE 64
|
||||
#define DEFAULT_CACHE_PAGES 512
|
||||
#define DEFAULT_SECTORS_PAGE 128
|
||||
#if 0
|
||||
#define USE_LWP_LOCK
|
||||
#define USE_RTC_TIME
|
||||
|
25
deps/libiosuhax/.github/workflows/push_image.yml
vendored
Normal file
25
deps/libiosuhax/.github/workflows/push_image.yml
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
name: Publish Docker Image
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@master
|
||||
- name: Get release version
|
||||
id: get_release_tag
|
||||
run: |
|
||||
echo RELEASE_VERSION=$(echo $(date '+%Y%m%d')) >> $GITHUB_ENV
|
||||
echo REPOSITORY_NAME=$(echo "$GITHUB_REPOSITORY" | awk -F / '{print $2}' | sed -e "s/:refs//" | tr '[:upper:]' '[:lower:]') >> $GITHUB_ENV
|
||||
echo REPOSITORY_OWNER=$(echo "$GITHUB_REPOSITORY" | awk -F / '{print $1}' | sed 's/[^a-zA-Z0-9]//g' | tr '[:upper:]' '[:lower:]') >> $GITHUB_ENV
|
||||
- name: Publish to Registry
|
||||
uses: elgohr/Publish-Docker-Github-Action@master
|
||||
with:
|
||||
name: ${{ env.REPOSITORY_OWNER }}/${{ env.REPOSITORY_NAME }}
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
snapshot: true
|
||||
cache: true
|
||||
tags: "latest, ${{ env.RELEASE_VERSION }}"
|
5
deps/libiosuhax/.gitignore
vendored
Normal file
5
deps/libiosuhax/.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
/*.a
|
||||
/build
|
||||
*.bz2
|
||||
release/
|
||||
lib/
|
29
deps/libiosuhax/.travis.yml
vendored
Normal file
29
deps/libiosuhax/.travis.yml
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
language: cpp
|
||||
|
||||
os: linux
|
||||
sudo: false
|
||||
dist: trusty
|
||||
|
||||
env:
|
||||
global:
|
||||
- DEVKITPRO=/opt/devkitpro
|
||||
- DEVKITPPC=/opt/devkitpro/devkitPPC
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- "$HOME/.local"
|
||||
- "$DEVKITPRO"
|
||||
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- p7zip-full
|
||||
|
||||
before_install:
|
||||
- mkdir -p "${DEVKITPRO}"
|
||||
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then wget https://github.com/devkitPro/pacman/releases/download/devkitpro-pacman-1.0.1/devkitpro-pacman.deb -O /tmp/devkitpro-pacman.deb; fi
|
||||
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo dpkg -i /tmp/devkitpro-pacman.deb; fi
|
||||
- yes | sudo dkp-pacman -Syu devkitPPC --needed
|
||||
|
||||
script:
|
||||
- make && make install
|
9
deps/libiosuhax/Dockerfile
vendored
Normal file
9
deps/libiosuhax/Dockerfile
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
FROM wiiuenv/devkitppc:20210101
|
||||
|
||||
WORKDIR tmp_build
|
||||
COPY . .
|
||||
RUN make clean && make && mkdir -p /artifacts/wut/usr && cp -r lib /artifacts/wut/usr && cp -r include /artifacts/wut/usr
|
||||
WORKDIR /artifacts
|
||||
|
||||
FROM scratch
|
||||
COPY --from=0 /artifacts /artifacts
|
157
deps/libiosuhax/Makefile
vendored
Normal file
157
deps/libiosuhax/Makefile
vendored
Normal file
@ -0,0 +1,157 @@
|
||||
#-------------------------------------------------------------------------------
|
||||
.SUFFIXES:
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
ifeq ($(strip $(DEVKITPRO)),)
|
||||
$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=<path to>/devkitpro")
|
||||
endif
|
||||
|
||||
TOPDIR ?= $(CURDIR)
|
||||
|
||||
include $(DEVKITPRO)/wut/share/wut_rules
|
||||
|
||||
export VER_MAJOR := 1
|
||||
export VER_MINOR := 0
|
||||
export VER_PATCH := 0
|
||||
|
||||
VERSION := $(VER_MAJOR).$(VER_MINOR).$(VER_PATCH)
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# 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
|
||||
# DATA is a list of directories containing data files
|
||||
# INCLUDES is a list of directories containing header files
|
||||
#-------------------------------------------------------------------------------
|
||||
TARGET := $(notdir $(CURDIR))
|
||||
BUILD := build
|
||||
SOURCES := source
|
||||
DATA := data
|
||||
INCLUDES := source \
|
||||
include \
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# options for code generation
|
||||
#---------------------------------------------------------------------------------
|
||||
CFLAGS := -Wall -Werror -save-temps \
|
||||
-ffunction-sections -fdata-sections \
|
||||
$(MACHDEP) \
|
||||
$(BUILD_CFLAGS)
|
||||
|
||||
CFLAGS += $(INCLUDE) -D__WIIU__ -D__WUT__
|
||||
|
||||
CXXFLAGS := $(CFLAGS) -std=gnu++17
|
||||
|
||||
ASFLAGS := $(MACHDEP)
|
||||
|
||||
LDFLAGS = $(ARCH) -Wl,--gc-sections
|
||||
|
||||
|
||||
LIBS :=
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# list of directories containing libraries, this must be the top level containing
|
||||
# include and lib
|
||||
#---------------------------------------------------------------------------------
|
||||
LIBDIRS := $(PORTLIBS) $(WUT_ROOT)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# no real need to edit anything past this point unless you need to add additional
|
||||
# rules for different file extensions
|
||||
#---------------------------------------------------------------------------------
|
||||
ifneq ($(BUILD),$(notdir $(CURDIR)))
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
export TOPDIR := $(CURDIR)
|
||||
|
||||
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
|
||||
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
|
||||
|
||||
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
|
||||
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
|
||||
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
|
||||
DEFFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.def)))
|
||||
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# use CXX for linking C++ projects, CC for standard C
|
||||
#---------------------------------------------------------------------------------
|
||||
ifeq ($(strip $(CPPFILES)),)
|
||||
#---------------------------------------------------------------------------------
|
||||
export LD := $(CC)
|
||||
#---------------------------------------------------------------------------------
|
||||
else
|
||||
#---------------------------------------------------------------------------------
|
||||
export LD := $(CXX)
|
||||
#---------------------------------------------------------------------------------
|
||||
endif
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
export OFILES_BIN := $(addsuffix .o,$(BINFILES))
|
||||
export OFILES_SRC := $(DEFFILES:.def=.o) $(SFILES:.s=.o) $(CFILES:.c=.o) $(CPPFILES:.cpp=.o)
|
||||
export OFILES := $(OFILES_BIN) $(OFILES_SRC)
|
||||
export HFILES := $(addsuffix .h,$(subst .,_,$(BINFILES)))
|
||||
|
||||
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
|
||||
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
|
||||
-I.
|
||||
|
||||
.PHONY: all dist-bin dist-src dist install clean
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
all: lib/libiosuhax.a
|
||||
|
||||
dist-bin: all
|
||||
@tar --exclude=*~ -cjf libiosuhax-$(VERSION).tar.bz2 include lib
|
||||
|
||||
dist-src:
|
||||
@tar --exclude=*~ -cjf libiosuhax-src-$(VERSION).tar.bz2 include source Makefile
|
||||
|
||||
dist: dist-src dist-bin
|
||||
|
||||
install: dist-bin
|
||||
mkdir -p $(DESTDIR)$(DEVKITPRO)/wut/usr
|
||||
bzip2 -cd libiosuhax-$(VERSION).tar.bz2 | tar -xf - -C $(DESTDIR)$(DEVKITPRO)/wut/usr
|
||||
|
||||
lib:
|
||||
@[ -d $@ ] || mkdir -p $@
|
||||
|
||||
release:
|
||||
@[ -d $@ ] || mkdir -p $@
|
||||
|
||||
lib/libiosuhax.a :$(SOURCES) $(INCLUDES) | lib release
|
||||
@$(MAKE) BUILD=release OUTPUT=$(CURDIR)/$@ \
|
||||
BUILD_CFLAGS="-DNDEBUG=1 -O2 -s" \
|
||||
DEPSDIR=$(CURDIR)/release \
|
||||
--no-print-directory -C release \
|
||||
-f $(CURDIR)/Makefile
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
clean:
|
||||
@echo clean ...
|
||||
@rm -rf release lib
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
else
|
||||
|
||||
DEPENDS := $(OFILES:.o=.d)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# main targets
|
||||
#---------------------------------------------------------------------------------
|
||||
$(OUTPUT) : $(OFILES)
|
||||
|
||||
$(OFILES_SRC) : $(HFILES)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
%_bin.h %.bin.o : %.bin
|
||||
#---------------------------------------------------------------------------------
|
||||
@echo $(notdir $<)
|
||||
@$(bin2o)
|
||||
|
||||
|
||||
-include $(DEPENDS)
|
||||
|
||||
#---------------------------------------------------------------------------------------
|
||||
endif
|
||||
#---------------------------------------------------------------------------------------
|
10
deps/libiosuhax/README.md
vendored
Normal file
10
deps/libiosuhax/README.md
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
[](https://travis-ci.org/dimok789/libiosuhax)
|
||||
# libiosuhax
|
||||
A PPC library to access IOSUHAX from PPC and a devoptab for any device or path.
|
||||
It's only compatible to RPX-Files.
|
||||
|
||||
## Building
|
||||
Make you to have [wut](https://github.com/devkitPro/wut/) installed and use the following command for build:
|
||||
```
|
||||
make install
|
||||
```
|
@ -69,6 +69,9 @@ int IOSUHAX_memwrite(uint32_t address, const uint8_t * buffer, uint32_t size); /
|
||||
int IOSUHAX_memread(uint32_t address, uint8_t * out_buffer, uint32_t size); // IOSU external output
|
||||
int IOSUHAX_memcpy(uint32_t dst, uint32_t src, uint32_t size); // IOSU internal memcpy only
|
||||
|
||||
int IOSUHAX_kern_write32(uint32_t address, uint32_t value);
|
||||
int IOSUHAX_kern_read32(uint32_t address, uint32_t* out_buffer, uint32_t count);
|
||||
|
||||
int IOSUHAX_SVC(uint32_t svc_id, uint32_t * args, uint32_t arg_cnt);
|
||||
|
||||
int IOSUHAX_FSA_Open();
|
51
deps/libiosuhax/os_functions.h
vendored
51
deps/libiosuhax/os_functions.h
vendored
@ -1,51 +0,0 @@
|
||||
#ifndef __OS_FUNCTIONS_H_
|
||||
#define __OS_FUNCTIONS_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define OS_MUTEX_SIZE 44
|
||||
|
||||
// RetroArch mod: use existing headers; prevents conflicts in griffin
|
||||
#include <wiiu/os.h>
|
||||
#include <wiiu/ios.h>
|
||||
#if 0
|
||||
|
||||
#ifndef __WUT__
|
||||
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
//! Mutex functions
|
||||
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
extern void (* OSInitMutex)(void* mutex);
|
||||
extern void (* OSLockMutex)(void* mutex);
|
||||
extern void (* OSUnlockMutex)(void* mutex);
|
||||
|
||||
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
//! IOS function
|
||||
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
extern int (*IOS_Ioctl)(int fd, unsigned int request, void *input_buffer,unsigned int input_buffer_len, void *output_buffer, unsigned int output_buffer_len);
|
||||
extern int (*IOS_Open)(char *path, unsigned int mode);
|
||||
extern int (*IOS_Close)(int fd);
|
||||
#else
|
||||
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
//! Mutex functions
|
||||
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
extern void OSInitMutex(void* mutex);
|
||||
extern void OSLockMutex(void* mutex);
|
||||
extern void OSUnlockMutex(void* mutex);
|
||||
|
||||
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
//! IOS function
|
||||
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
extern int IOS_Ioctl(int fd, unsigned int request, void *input_buffer,unsigned int input_buffer_len, void *output_buffer, unsigned int output_buffer_len);
|
||||
extern int IOS_Open(char *path, unsigned int mode);
|
||||
extern int IOS_Close(int fd);
|
||||
#endif // __WUT__
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // 0
|
||||
|
||||
#endif // __OS_FUNCTIONS_H_
|
@ -66,17 +66,22 @@
|
||||
|
||||
static int iosuhaxHandle = -1;
|
||||
|
||||
#define ALIGN(align) __attribute__((aligned(align)))
|
||||
#define ROUNDUP(x, align) (((x) + ((align) - 1)) & ~((align) - 1))
|
||||
|
||||
int IOSUHAX_Open(const char *dev)
|
||||
{
|
||||
if(iosuhaxHandle >= 0)
|
||||
return iosuhaxHandle;
|
||||
|
||||
iosuhaxHandle = IOS_Open((char*)(dev ? dev : "/dev/iosuhax"), 0);
|
||||
if(iosuhaxHandle >= 0 && dev) /* make sure device is actually iosuhax */
|
||||
if(iosuhaxHandle >= 0 && dev) //make sure device is actually iosuhax
|
||||
{
|
||||
unsigned int res = 0;
|
||||
IOS_Ioctl(iosuhaxHandle, IOCTL_CHECK_IF_IOSUHAX, (void*)0, 0, &res, 4);
|
||||
if(res != IOSUHAX_MAGIC_WORD)
|
||||
ALIGN(0x20) int res[0x20 >> 2];
|
||||
*res = 0;
|
||||
|
||||
IOS_Ioctl(iosuhaxHandle, IOCTL_CHECK_IF_IOSUHAX, (void*)0, 0, res, 4);
|
||||
if(*res != IOSUHAX_MAGIC_WORD)
|
||||
{
|
||||
IOS_Close(iosuhaxHandle);
|
||||
iosuhaxHandle = -1;
|
||||
@ -101,10 +106,7 @@ int IOSUHAX_memwrite(uint32_t address, const uint8_t * buffer, uint32_t size)
|
||||
if(iosuhaxHandle < 0)
|
||||
return iosuhaxHandle;
|
||||
|
||||
if(!buffer)
|
||||
return -1;
|
||||
|
||||
uint32_t *io_buf = (uint32_t*)memalign(0x20, size + 4);
|
||||
uint32_t *io_buf = (uint32_t*)memalign(0x20, ROUNDUP(size + 4, 0x20));
|
||||
if(!io_buf)
|
||||
return -2;
|
||||
|
||||
@ -122,10 +124,25 @@ int IOSUHAX_memread(uint32_t address, uint8_t * out_buffer, uint32_t size)
|
||||
if(iosuhaxHandle < 0)
|
||||
return iosuhaxHandle;
|
||||
|
||||
if(!out_buffer || !size)
|
||||
return -1;
|
||||
ALIGN(0x20) int io_buf[0x20 >> 2];
|
||||
io_buf[0] = address;
|
||||
|
||||
return IOS_Ioctl(iosuhaxHandle, IOCTL_MEM_READ, &address, sizeof(address), out_buffer, size);
|
||||
void* tmp_buf = NULL;
|
||||
|
||||
if(((uintptr_t)out_buffer & 0x1F) || (size & 0x1F))
|
||||
{
|
||||
tmp_buf = (uint32_t*)memalign(0x20, ROUNDUP(size, 0x20));
|
||||
if(!tmp_buf)
|
||||
return -2;
|
||||
}
|
||||
|
||||
int res = IOS_Ioctl(iosuhaxHandle, IOCTL_MEM_READ, io_buf, sizeof(address), tmp_buf ? tmp_buf : out_buffer, size);
|
||||
|
||||
if(res >= 0 && tmp_buf)
|
||||
memcpy(out_buffer, tmp_buf, size);
|
||||
|
||||
free(tmp_buf);
|
||||
return res;
|
||||
}
|
||||
|
||||
int IOSUHAX_memcpy(uint32_t dst, uint32_t src, uint32_t size)
|
||||
@ -133,15 +150,50 @@ int IOSUHAX_memcpy(uint32_t dst, uint32_t src, uint32_t size)
|
||||
if(iosuhaxHandle < 0)
|
||||
return iosuhaxHandle;
|
||||
|
||||
if(!dst || !src || !size)
|
||||
return -1;
|
||||
|
||||
uint32_t io_buf[3];
|
||||
ALIGN(0x20) uint32_t io_buf[0x20 >> 2];
|
||||
io_buf[0] = dst;
|
||||
io_buf[1] = src;
|
||||
io_buf[2] = size;
|
||||
|
||||
return IOS_Ioctl(iosuhaxHandle, IOCTL_MEMCPY, io_buf, sizeof(io_buf), 0, 0);
|
||||
return IOS_Ioctl(iosuhaxHandle, IOCTL_MEMCPY, io_buf, 3 * sizeof(uint32_t), 0, 0);
|
||||
}
|
||||
|
||||
int IOSUHAX_kern_write32(uint32_t address, uint32_t value)
|
||||
{
|
||||
if(iosuhaxHandle < 0)
|
||||
return iosuhaxHandle;
|
||||
|
||||
ALIGN(0x20) uint32_t io_buf[0x20 >> 2];
|
||||
io_buf[0] = address;
|
||||
io_buf[1] = value;
|
||||
|
||||
return IOS_Ioctl(iosuhaxHandle, IOCTL_KERN_WRITE32, io_buf, 2 * sizeof(uint32_t), 0, 0);
|
||||
}
|
||||
|
||||
int IOSUHAX_kern_read32(uint32_t address, uint32_t* out_buffer, uint32_t count)
|
||||
{
|
||||
if(iosuhaxHandle < 0)
|
||||
return iosuhaxHandle;
|
||||
|
||||
ALIGN(0x20) uint32_t io_buf[0x20 >> 2];
|
||||
io_buf[0] = address;
|
||||
|
||||
void* tmp_buf = NULL;
|
||||
|
||||
if(((uintptr_t)out_buffer & 0x1F) || ((count * 4) & 0x1F))
|
||||
{
|
||||
tmp_buf = (uint32_t*)memalign(0x20, ROUNDUP((count * 4), 0x20));
|
||||
if(!tmp_buf)
|
||||
return -2;
|
||||
}
|
||||
|
||||
int res = IOS_Ioctl(iosuhaxHandle, IOCTL_KERN_READ32, io_buf, sizeof(address), tmp_buf ? tmp_buf : out_buffer, count * 4);
|
||||
|
||||
if(res >= 0 && tmp_buf)
|
||||
memcpy(out_buffer, tmp_buf, count * 4);
|
||||
|
||||
free(tmp_buf);
|
||||
return res;
|
||||
}
|
||||
|
||||
int IOSUHAX_SVC(uint32_t svc_id, uint32_t * args, uint32_t arg_cnt)
|
||||
@ -149,7 +201,7 @@ int IOSUHAX_SVC(uint32_t svc_id, uint32_t * args, uint32_t arg_cnt)
|
||||
if(iosuhaxHandle < 0)
|
||||
return iosuhaxHandle;
|
||||
|
||||
uint32_t arguments[9];
|
||||
ALIGN(0x20) uint32_t arguments[0x40 >> 2];
|
||||
arguments[0] = svc_id;
|
||||
|
||||
if(args && arg_cnt)
|
||||
@ -160,12 +212,12 @@ int IOSUHAX_SVC(uint32_t svc_id, uint32_t * args, uint32_t arg_cnt)
|
||||
memcpy(arguments + 1, args, arg_cnt * 4);
|
||||
}
|
||||
|
||||
int result;
|
||||
int ret = IOS_Ioctl(iosuhaxHandle, IOCTL_SVC, arguments, (1 + arg_cnt) * 4, &result, sizeof(result));
|
||||
ALIGN(0x20) int result[0x20 >> 2];
|
||||
int ret = IOS_Ioctl(iosuhaxHandle, IOCTL_SVC, arguments, (1 + arg_cnt) * 4, result, 4);
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
|
||||
return result;
|
||||
return *result;
|
||||
}
|
||||
|
||||
int IOSUHAX_FSA_Open(void)
|
||||
@ -173,13 +225,13 @@ int IOSUHAX_FSA_Open(void)
|
||||
if(iosuhaxHandle < 0)
|
||||
return iosuhaxHandle;
|
||||
|
||||
int fsaFd;
|
||||
ALIGN(0x20) int io_buf[0x20 >> 2];
|
||||
|
||||
int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_OPEN, 0, 0, &fsaFd, sizeof(fsaFd));
|
||||
int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_OPEN, 0, 0, io_buf, sizeof(int));
|
||||
if(res < 0)
|
||||
return res;
|
||||
|
||||
return fsaFd;
|
||||
return io_buf[0];
|
||||
}
|
||||
|
||||
int IOSUHAX_FSA_Close(int fsaFd)
|
||||
@ -187,11 +239,14 @@ int IOSUHAX_FSA_Close(int fsaFd)
|
||||
if(iosuhaxHandle < 0)
|
||||
return iosuhaxHandle;
|
||||
|
||||
int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_CLOSE, &fsaFd, sizeof(fsaFd), &fsaFd, sizeof(fsaFd));
|
||||
ALIGN(0x20) int io_buf[0x20 >> 2];
|
||||
io_buf[0] = fsaFd;
|
||||
|
||||
int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_CLOSE, io_buf, sizeof(fsaFd), io_buf, sizeof(fsaFd));
|
||||
if(res < 0)
|
||||
return res;
|
||||
|
||||
return fsaFd;
|
||||
return io_buf[0];
|
||||
}
|
||||
|
||||
int IOSUHAX_FSA_Mount(int fsaFd, const char* device_path, const char* volume_path, uint32_t flags, const char* arg_string, int arg_string_len)
|
||||
@ -199,18 +254,13 @@ int IOSUHAX_FSA_Mount(int fsaFd, const char* device_path, const char* volume_pat
|
||||
if(iosuhaxHandle < 0)
|
||||
return iosuhaxHandle;
|
||||
|
||||
if(!device_path || !volume_path || !arg_string)
|
||||
return -1;
|
||||
|
||||
const int input_cnt = 6;
|
||||
|
||||
int io_buf_size = (sizeof(uint32_t) * input_cnt) + strlen(device_path) + strlen(volume_path) + arg_string_len + 3;
|
||||
|
||||
uint32_t *io_buf = (uint32_t*)memalign(0x20, io_buf_size);
|
||||
if(!io_buf)
|
||||
return -2;
|
||||
|
||||
ALIGN(0x20) int io_buf[ROUNDUP(io_buf_size, 0x20) >> 2];
|
||||
memset(io_buf, 0, io_buf_size);
|
||||
|
||||
io_buf[0] = fsaFd;
|
||||
io_buf[1] = sizeof(uint32_t) * input_cnt;
|
||||
io_buf[2] = io_buf[1] + strlen(device_path) + 1;
|
||||
@ -224,17 +274,11 @@ int IOSUHAX_FSA_Mount(int fsaFd, const char* device_path, const char* volume_pat
|
||||
if(arg_string_len)
|
||||
memcpy(((char*)io_buf) + io_buf[4], arg_string, arg_string_len);
|
||||
|
||||
int mountRes;
|
||||
|
||||
int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_MOUNT, io_buf, io_buf_size, &mountRes, sizeof(mountRes));
|
||||
int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_MOUNT, io_buf, io_buf_size, io_buf, 4);
|
||||
if(res < 0)
|
||||
{
|
||||
free(io_buf);
|
||||
return res;
|
||||
}
|
||||
return res;
|
||||
|
||||
free(io_buf);
|
||||
return mountRes;
|
||||
return io_buf[0];
|
||||
}
|
||||
|
||||
int IOSUHAX_FSA_Unmount(int fsaFd, const char* path, uint32_t flags)
|
||||
@ -242,33 +286,22 @@ int IOSUHAX_FSA_Unmount(int fsaFd, const char* path, uint32_t flags)
|
||||
if(iosuhaxHandle < 0)
|
||||
return iosuhaxHandle;
|
||||
|
||||
if(!path)
|
||||
return -1;
|
||||
|
||||
const int input_cnt = 3;
|
||||
|
||||
int io_buf_size = sizeof(uint32_t) * input_cnt + strlen(path) + 1;
|
||||
|
||||
uint32_t *io_buf = (uint32_t*)memalign(0x20, io_buf_size);
|
||||
if(!io_buf)
|
||||
return -2;
|
||||
ALIGN(0x20) int io_buf[ROUNDUP(io_buf_size, 0x20) >> 2];
|
||||
|
||||
io_buf[0] = fsaFd;
|
||||
io_buf[1] = sizeof(uint32_t) * input_cnt;
|
||||
io_buf[2] = flags;
|
||||
strcpy(((char*)io_buf) + io_buf[1], path);
|
||||
|
||||
int result;
|
||||
|
||||
int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_UNMOUNT, io_buf, io_buf_size, &result, sizeof(result));
|
||||
int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_UNMOUNT, io_buf, io_buf_size, io_buf, 4);
|
||||
if(res < 0)
|
||||
{
|
||||
free(io_buf);
|
||||
return res;
|
||||
}
|
||||
return res;
|
||||
|
||||
free(io_buf);
|
||||
return result;
|
||||
return io_buf[0];
|
||||
}
|
||||
|
||||
int IOSUHAX_FSA_FlushVolume(int fsaFd, const char *volume_path)
|
||||
@ -276,32 +309,21 @@ int IOSUHAX_FSA_FlushVolume(int fsaFd, const char *volume_path)
|
||||
if(iosuhaxHandle < 0)
|
||||
return iosuhaxHandle;
|
||||
|
||||
if(!volume_path)
|
||||
return -1;
|
||||
|
||||
const int input_cnt = 2;
|
||||
|
||||
int io_buf_size = sizeof(uint32_t) * input_cnt + strlen(volume_path) + 1;
|
||||
|
||||
uint32_t *io_buf = (uint32_t*)memalign(0x20, io_buf_size);
|
||||
if(!io_buf)
|
||||
return -2;
|
||||
ALIGN(0x20) int io_buf[ROUNDUP(io_buf_size, 0x20) >> 2];
|
||||
|
||||
io_buf[0] = fsaFd;
|
||||
io_buf[1] = sizeof(uint32_t) * input_cnt;
|
||||
strcpy(((char*)io_buf) + io_buf[1], volume_path);
|
||||
|
||||
int result;
|
||||
|
||||
int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_FLUSHVOLUME, io_buf, io_buf_size, &result, sizeof(result));
|
||||
int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_FLUSHVOLUME, io_buf, io_buf_size, io_buf, 4);
|
||||
if(res < 0)
|
||||
{
|
||||
free(io_buf);
|
||||
return res;
|
||||
}
|
||||
|
||||
free(io_buf);
|
||||
return result;
|
||||
return io_buf[0];
|
||||
}
|
||||
|
||||
int IOSUHAX_FSA_GetDeviceInfo(int fsaFd, const char* device_path, int type, uint32_t* out_data)
|
||||
@ -309,9 +331,6 @@ int IOSUHAX_FSA_GetDeviceInfo(int fsaFd, const char* device_path, int type, uint
|
||||
if(iosuhaxHandle < 0)
|
||||
return iosuhaxHandle;
|
||||
|
||||
if(!device_path || !out_data)
|
||||
return -1;
|
||||
|
||||
const int input_cnt = 3;
|
||||
|
||||
int io_buf_size = sizeof(uint32_t) * input_cnt + strlen(device_path) + 1;
|
||||
@ -344,9 +363,6 @@ int IOSUHAX_FSA_MakeDir(int fsaFd, const char* path, uint32_t flags)
|
||||
if(iosuhaxHandle < 0)
|
||||
return iosuhaxHandle;
|
||||
|
||||
if(!path)
|
||||
return -1;
|
||||
|
||||
const int input_cnt = 3;
|
||||
|
||||
int io_buf_size = sizeof(uint32_t) * input_cnt + strlen(path) + 1;
|
||||
@ -377,9 +393,6 @@ int IOSUHAX_FSA_OpenDir(int fsaFd, const char* path, int* outHandle)
|
||||
if(iosuhaxHandle < 0)
|
||||
return iosuhaxHandle;
|
||||
|
||||
if(!path)
|
||||
return -1;
|
||||
|
||||
const int input_cnt = 2;
|
||||
|
||||
int io_buf_size = sizeof(uint32_t) * input_cnt + strlen(path) + 1;
|
||||
@ -411,9 +424,6 @@ int IOSUHAX_FSA_ReadDir(int fsaFd, int handle, directoryEntry_s* out_data)
|
||||
if(iosuhaxHandle < 0)
|
||||
return iosuhaxHandle;
|
||||
|
||||
if(!out_data)
|
||||
return -1;
|
||||
|
||||
const int input_cnt = 2;
|
||||
|
||||
int io_buf_size = sizeof(uint32_t) * input_cnt;
|
||||
@ -511,9 +521,6 @@ int IOSUHAX_FSA_ChangeDir(int fsaFd, const char *path)
|
||||
if(iosuhaxHandle < 0)
|
||||
return iosuhaxHandle;
|
||||
|
||||
if(!path)
|
||||
return -1;
|
||||
|
||||
const int input_cnt = 2;
|
||||
|
||||
int io_buf_size = sizeof(uint32_t) * input_cnt + strlen(path) + 1;
|
||||
@ -544,9 +551,6 @@ int IOSUHAX_FSA_OpenFile(int fsaFd, const char* path, const char* mode, int* out
|
||||
if(iosuhaxHandle < 0)
|
||||
return iosuhaxHandle;
|
||||
|
||||
if(!path || !mode || !outHandle)
|
||||
return -1;
|
||||
|
||||
const int input_cnt = 3;
|
||||
|
||||
int io_buf_size = sizeof(uint32_t) * input_cnt + strlen(path) + strlen(mode) + 2;
|
||||
@ -580,9 +584,6 @@ int IOSUHAX_FSA_ReadFile(int fsaFd, void* data, uint32_t size, uint32_t cnt, int
|
||||
if(iosuhaxHandle < 0)
|
||||
return iosuhaxHandle;
|
||||
|
||||
if(!data)
|
||||
return -1;
|
||||
|
||||
const int input_cnt = 5;
|
||||
|
||||
int io_buf_size = sizeof(uint32_t) * input_cnt;
|
||||
@ -614,7 +615,7 @@ int IOSUHAX_FSA_ReadFile(int fsaFd, void* data, uint32_t size, uint32_t cnt, int
|
||||
return res;
|
||||
}
|
||||
|
||||
/* ! data is put to offset 0x40 to align the buffer output */
|
||||
//! data is put to offset 0x40 to align the buffer output
|
||||
memcpy(data, ((uint8_t*)out_buffer) + 0x40, size * cnt);
|
||||
|
||||
int result = out_buffer[0];
|
||||
@ -629,9 +630,6 @@ int IOSUHAX_FSA_WriteFile(int fsaFd, const void* data, uint32_t size, uint32_t c
|
||||
if(iosuhaxHandle < 0)
|
||||
return iosuhaxHandle;
|
||||
|
||||
if(!data)
|
||||
return -1;
|
||||
|
||||
const int input_cnt = 5;
|
||||
|
||||
int io_buf_size = ((sizeof(uint32_t) * input_cnt + size * cnt + 0x40) + 0x3F) & ~0x3F;
|
||||
@ -646,7 +644,7 @@ int IOSUHAX_FSA_WriteFile(int fsaFd, const void* data, uint32_t size, uint32_t c
|
||||
io_buf[3] = fileHandle;
|
||||
io_buf[4] = flags;
|
||||
|
||||
/* ! data is put to offset 0x40 to align the buffer input */
|
||||
//! data is put to offset 0x40 to align the buffer input
|
||||
memcpy(((uint8_t*)io_buf) + 0x40, data, size * cnt);
|
||||
|
||||
int result;
|
||||
@ -665,9 +663,6 @@ int IOSUHAX_FSA_StatFile(int fsaFd, int fileHandle, fileStat_s* out_data)
|
||||
if(iosuhaxHandle < 0)
|
||||
return iosuhaxHandle;
|
||||
|
||||
if(!out_data)
|
||||
return -1;
|
||||
|
||||
const int input_cnt = 2;
|
||||
|
||||
int io_buf_size = sizeof(uint32_t) * input_cnt;
|
||||
@ -767,9 +762,6 @@ int IOSUHAX_FSA_GetStat(int fsaFd, const char *path, fileStat_s* out_data)
|
||||
if(iosuhaxHandle < 0)
|
||||
return iosuhaxHandle;
|
||||
|
||||
if(!path || !out_data)
|
||||
return -1;
|
||||
|
||||
const int input_cnt = 2;
|
||||
|
||||
int io_buf_size = sizeof(uint32_t) * input_cnt + strlen(path) + 1;
|
||||
@ -811,14 +803,11 @@ int IOSUHAX_FSA_Remove(int fsaFd, const char *path)
|
||||
if(iosuhaxHandle < 0)
|
||||
return iosuhaxHandle;
|
||||
|
||||
if(!path)
|
||||
return -1;
|
||||
|
||||
const int input_cnt = 2;
|
||||
|
||||
int io_buf_size = sizeof(uint32_t) * input_cnt + strlen(path) + 1;
|
||||
|
||||
uint32_t *io_buf = (uint32_t*)memalign(0x20, io_buf_size);
|
||||
uint32_t *io_buf = (uint32_t*)memalign(0x20, ROUNDUP(io_buf_size, 0x20));
|
||||
if(!io_buf)
|
||||
return -2;
|
||||
|
||||
@ -826,17 +815,12 @@ int IOSUHAX_FSA_Remove(int fsaFd, const char *path)
|
||||
io_buf[1] = sizeof(uint32_t) * input_cnt;
|
||||
strcpy(((char*)io_buf) + io_buf[1], path);
|
||||
|
||||
int result;
|
||||
|
||||
int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_REMOVE, io_buf, io_buf_size, &result, sizeof(result));
|
||||
if(res < 0)
|
||||
{
|
||||
free(io_buf);
|
||||
return res;
|
||||
}
|
||||
int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_REMOVE, io_buf, io_buf_size, io_buf, 4);
|
||||
if(res >= 0)
|
||||
res = io_buf[0];
|
||||
|
||||
free(io_buf);
|
||||
return result;
|
||||
return res;
|
||||
}
|
||||
|
||||
int IOSUHAX_FSA_ChangeMode(int fsaFd, const char* path, int mode)
|
||||
@ -844,33 +828,22 @@ int IOSUHAX_FSA_ChangeMode(int fsaFd, const char* path, int mode)
|
||||
if(iosuhaxHandle < 0)
|
||||
return iosuhaxHandle;
|
||||
|
||||
if(!path)
|
||||
return -1;
|
||||
|
||||
const int input_cnt = 3;
|
||||
|
||||
int io_buf_size = sizeof(uint32_t) * input_cnt + strlen(path) + 1;
|
||||
|
||||
uint32_t *io_buf = (uint32_t*)memalign(0x20, io_buf_size);
|
||||
if(!io_buf)
|
||||
return -2;
|
||||
ALIGN(0x20) uint32_t io_buf[ROUNDUP(io_buf_size, 0x20) >> 2];
|
||||
|
||||
io_buf[0] = fsaFd;
|
||||
io_buf[1] = sizeof(uint32_t) * input_cnt;
|
||||
io_buf[2] = mode;
|
||||
strcpy(((char*)io_buf) + io_buf[1], path);
|
||||
|
||||
int result;
|
||||
|
||||
int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_CHANGEMODE, io_buf, io_buf_size, &result, sizeof(result));
|
||||
int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_CHANGEMODE, io_buf, io_buf_size, io_buf, 4);
|
||||
if(res < 0)
|
||||
{
|
||||
free(io_buf);
|
||||
return res;
|
||||
}
|
||||
return res;
|
||||
|
||||
free(io_buf);
|
||||
return result;
|
||||
return io_buf[0];
|
||||
}
|
||||
|
||||
int IOSUHAX_FSA_RawOpen(int fsaFd, const char* device_path, int* outHandle)
|
||||
@ -878,35 +851,24 @@ int IOSUHAX_FSA_RawOpen(int fsaFd, const char* device_path, int* outHandle)
|
||||
if(iosuhaxHandle < 0)
|
||||
return iosuhaxHandle;
|
||||
|
||||
if(!device_path && !outHandle)
|
||||
return -1;
|
||||
|
||||
const int input_cnt = 2;
|
||||
|
||||
int io_buf_size = sizeof(uint32_t) * input_cnt + strlen(device_path) + 1;
|
||||
|
||||
uint32_t *io_buf = (uint32_t*)memalign(0x20, io_buf_size);
|
||||
if(!io_buf)
|
||||
return -2;
|
||||
ALIGN(0x20) uint32_t io_buf[ROUNDUP(io_buf_size, 0x20) >> 2];
|
||||
|
||||
io_buf[0] = fsaFd;
|
||||
io_buf[1] = sizeof(uint32_t) * input_cnt;
|
||||
strcpy(((char*)io_buf) + io_buf[1], device_path);
|
||||
|
||||
int result_vec[2];
|
||||
|
||||
int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_RAW_OPEN, io_buf, io_buf_size, result_vec, sizeof(result_vec));
|
||||
int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_RAW_OPEN, io_buf, io_buf_size, io_buf, 2 * sizeof(int));
|
||||
if(res < 0)
|
||||
{
|
||||
free(io_buf);
|
||||
return res;
|
||||
}
|
||||
|
||||
if(outHandle)
|
||||
*outHandle = result_vec[1];
|
||||
*outHandle = io_buf[1];
|
||||
|
||||
free(io_buf);
|
||||
return result_vec[0];
|
||||
return io_buf[0];
|
||||
}
|
||||
|
||||
int IOSUHAX_FSA_RawRead(int fsaFd, void* data, uint32_t block_size, uint32_t block_cnt, uint64_t sector_offset, int device_handle)
|
||||
@ -914,14 +876,11 @@ int IOSUHAX_FSA_RawRead(int fsaFd, void* data, uint32_t block_size, uint32_t blo
|
||||
if(iosuhaxHandle < 0)
|
||||
return iosuhaxHandle;
|
||||
|
||||
if(!data)
|
||||
return -1;
|
||||
|
||||
const int input_cnt = 6;
|
||||
|
||||
int io_buf_size = sizeof(uint32_t) * input_cnt;
|
||||
int io_buf_size = 0x40 + block_size * block_cnt;
|
||||
uint32_t *io_buf = (uint32_t*)memalign(0x40, ROUNDUP(io_buf_size, 0x40));
|
||||
|
||||
uint32_t *io_buf = (uint32_t*)memalign(0x20, io_buf_size);
|
||||
if(!io_buf)
|
||||
return -2;
|
||||
|
||||
@ -932,31 +891,17 @@ int IOSUHAX_FSA_RawRead(int fsaFd, void* data, uint32_t block_size, uint32_t blo
|
||||
io_buf[4] = sector_offset & 0xFFFFFFFF;
|
||||
io_buf[5] = device_handle;
|
||||
|
||||
int out_buf_size = ((block_size * block_cnt + 0x40) + 0x3F) & ~0x3F;
|
||||
|
||||
uint32_t *out_buffer = (uint32_t*)memalign(0x40, out_buf_size);
|
||||
if(!out_buffer)
|
||||
int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_RAW_READ, io_buf, sizeof(uint32_t) * input_cnt, io_buf, io_buf_size);
|
||||
if(res >= 0)
|
||||
{
|
||||
free(io_buf);
|
||||
return -2;
|
||||
//! data is put to offset 0x40 to align the buffer output
|
||||
memcpy(data, ((uint8_t*)io_buf) + 0x40, block_size * block_cnt);
|
||||
|
||||
res = io_buf[0];
|
||||
}
|
||||
|
||||
int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_RAW_READ, io_buf, io_buf_size, out_buffer, out_buf_size);
|
||||
if(res < 0)
|
||||
{
|
||||
free(out_buffer);
|
||||
free(io_buf);
|
||||
return res;
|
||||
}
|
||||
|
||||
/* ! data is put to offset 0x40 to align the buffer output */
|
||||
memcpy(data, ((uint8_t*)out_buffer) + 0x40, block_size * block_cnt);
|
||||
|
||||
int result = out_buffer[0];
|
||||
|
||||
free(out_buffer);
|
||||
free(io_buf);
|
||||
return result;
|
||||
return res;
|
||||
}
|
||||
|
||||
int IOSUHAX_FSA_RawWrite(int fsaFd, const void* data, uint32_t block_size, uint32_t block_cnt, uint64_t sector_offset, int device_handle)
|
||||
@ -964,14 +909,9 @@ int IOSUHAX_FSA_RawWrite(int fsaFd, const void* data, uint32_t block_size, uint3
|
||||
if(iosuhaxHandle < 0)
|
||||
return iosuhaxHandle;
|
||||
|
||||
if(!data)
|
||||
return -1;
|
||||
int io_buf_size = ROUNDUP(0x40 + block_size * block_cnt, 0x40);
|
||||
|
||||
const int input_cnt = 6;
|
||||
|
||||
int io_buf_size = ((sizeof(uint32_t) * input_cnt + block_size * block_cnt + 0x40) + 0x3F) & ~0x3F;
|
||||
|
||||
uint32_t *io_buf = (uint32_t*)memalign(0x20, io_buf_size);
|
||||
uint32_t *io_buf = (uint32_t*)memalign(0x40, io_buf_size);
|
||||
if(!io_buf)
|
||||
return -2;
|
||||
|
||||
@ -982,20 +922,15 @@ int IOSUHAX_FSA_RawWrite(int fsaFd, const void* data, uint32_t block_size, uint3
|
||||
io_buf[4] = sector_offset & 0xFFFFFFFF;
|
||||
io_buf[5] = device_handle;
|
||||
|
||||
/* ! data is put to offset 0x40 to align the buffer input */
|
||||
//! data is put to offset 0x40 to align the buffer input
|
||||
memcpy(((uint8_t*)io_buf) + 0x40, data, block_size * block_cnt);
|
||||
|
||||
int result;
|
||||
|
||||
int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_RAW_WRITE, io_buf, io_buf_size, &result, sizeof(result));
|
||||
if(res < 0)
|
||||
{
|
||||
free(io_buf);
|
||||
return res;
|
||||
}
|
||||
int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_RAW_WRITE, io_buf, io_buf_size, io_buf, 4);
|
||||
if(res >= 0)
|
||||
res = io_buf[0];
|
||||
|
||||
free(io_buf);
|
||||
return result;
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
@ -1008,22 +943,14 @@ int IOSUHAX_FSA_RawClose(int fsaFd, int device_handle)
|
||||
|
||||
int io_buf_size = sizeof(uint32_t) * input_cnt;
|
||||
|
||||
uint32_t *io_buf = (uint32_t*)memalign(0x20, io_buf_size);
|
||||
if(!io_buf)
|
||||
return -2;
|
||||
ALIGN(0x20) uint32_t io_buf[ROUNDUP(io_buf_size, 0x20) >> 2];
|
||||
|
||||
io_buf[0] = fsaFd;
|
||||
io_buf[1] = device_handle;
|
||||
|
||||
int result;
|
||||
|
||||
int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_RAW_CLOSE, io_buf, io_buf_size, &result, sizeof(result));
|
||||
int res = IOS_Ioctl(iosuhaxHandle, IOCTL_FSA_RAW_CLOSE, io_buf, io_buf_size, io_buf, 4);
|
||||
if(res < 0)
|
||||
{
|
||||
free(io_buf);
|
||||
return res;
|
||||
}
|
||||
return res;
|
||||
|
||||
free(io_buf);
|
||||
return result;
|
||||
return io_buf[0];
|
||||
}
|
@ -22,14 +22,15 @@
|
||||
* distribution.
|
||||
***************************************************************************/
|
||||
#include <errno.h>
|
||||
#include <sys/iosupport.h>
|
||||
#include <sys/statvfs.h>
|
||||
#include <sys/dirent.h>
|
||||
#include <sys/iosupport.h>
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
#include <stdint.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/iosupport.h>
|
||||
#include "os_functions.h"
|
||||
#include "iosuhax.h"
|
||||
|
||||
@ -64,10 +65,7 @@ static fs_dev_private_t *fs_dev_get_device_data(const char *path)
|
||||
char name[128] = {0};
|
||||
int i;
|
||||
|
||||
if(!path)
|
||||
return NULL;
|
||||
|
||||
/* Get the device name from the path */
|
||||
// Get the device name from the path
|
||||
strncpy(name, path, 127);
|
||||
strtok(name, ":/");
|
||||
|
||||
@ -89,11 +87,11 @@ static fs_dev_private_t *fs_dev_get_device_data(const char *path)
|
||||
|
||||
static char *fs_dev_real_path (const char *path, fs_dev_private_t *dev)
|
||||
{
|
||||
/* Sanity check */
|
||||
if (!path || !dev)
|
||||
// Sanity check
|
||||
if (!path)
|
||||
return NULL;
|
||||
|
||||
/* Move the path pointer to the start of the actual path */
|
||||
// Move the path pointer to the start of the actual path
|
||||
if (strchr(path, ':') != NULL) {
|
||||
path = strchr(path, ':') + 1;
|
||||
}
|
||||
@ -112,47 +110,56 @@ static char *fs_dev_real_path (const char *path, fs_dev_private_t *dev)
|
||||
static int fs_dev_open_r (struct _reent *r, void *fileStruct, const char *path, int flags, int mode)
|
||||
{
|
||||
fs_dev_private_t *dev = fs_dev_get_device_data(path);
|
||||
|
||||
if(!r)
|
||||
return -1;
|
||||
|
||||
if(!dev) {
|
||||
r->_errno = ENODEV;
|
||||
return -1;
|
||||
}
|
||||
|
||||
fs_dev_file_state_t *file = (fs_dev_file_state_t *)fileStruct;
|
||||
if(!file) {
|
||||
r->_errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
file->dev = dev;
|
||||
/* Determine which mode the file is opened for */
|
||||
// Determine which mode the file is opened for
|
||||
file->flags = flags;
|
||||
|
||||
const char *mode_str;
|
||||
const char *fsMode;
|
||||
|
||||
if ((flags & 0x03) == O_RDONLY) {
|
||||
// Map flags to open modes
|
||||
if (flags == 0) {
|
||||
file->read = 1;
|
||||
file->write = 0;
|
||||
file->append = 0;
|
||||
mode_str = "r";
|
||||
} else if ((flags & 0x03) == O_WRONLY) {
|
||||
file->read = 0;
|
||||
file->write = 1;
|
||||
file->append = (flags & O_APPEND);
|
||||
mode_str = file->append ? "a" : "w";
|
||||
} else if ((flags & 0x03) == O_RDWR) {
|
||||
fsMode = "r";
|
||||
} else if (flags == 2) {
|
||||
file->read = 1;
|
||||
file->write = 1;
|
||||
file->append = (flags & O_APPEND);
|
||||
mode_str = file->append ? "a+" : "r+";
|
||||
file->append = 0;
|
||||
fsMode = "r+";
|
||||
} else if (flags == 0x601) {
|
||||
file->read = 0;
|
||||
file->write = 1;
|
||||
file->append = 0;
|
||||
fsMode = "w";
|
||||
} else if(flags == 0x602) {
|
||||
file->read = 1;
|
||||
file->write = 1;
|
||||
file->append = 0;
|
||||
fsMode = "w+";
|
||||
} else if(flags == 0x209) {
|
||||
file->read = 0;
|
||||
file->write = 1;
|
||||
file->append = 1;
|
||||
fsMode = "a";
|
||||
} else if(flags == 0x20A) {
|
||||
file->read = 1;
|
||||
file->write = 1;
|
||||
file->append = 1;
|
||||
fsMode = "a+";
|
||||
} else {
|
||||
r->_errno = EACCES;
|
||||
r->_errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int fd = -1;
|
||||
|
||||
OSLockMutex(dev->pMutex);
|
||||
@ -164,7 +171,7 @@ static int fs_dev_open_r (struct _reent *r, void *fileStruct, const char *path,
|
||||
return -1;
|
||||
}
|
||||
|
||||
int result = IOSUHAX_FSA_OpenFile(dev->fsaFd, real_path, mode_str, &fd);
|
||||
int result = IOSUHAX_FSA_OpenFile(dev->fsaFd, real_path, fsMode, &fd);
|
||||
|
||||
free(real_path);
|
||||
|
||||
@ -190,18 +197,10 @@ static int fs_dev_open_r (struct _reent *r, void *fileStruct, const char *path,
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static int fs_dev_close_r (struct _reent *r, void *fd)
|
||||
{
|
||||
fs_dev_file_state_t *file = (fs_dev_file_state_t *)fd;
|
||||
|
||||
if(!r)
|
||||
return -1;
|
||||
|
||||
if(!file) {
|
||||
r->_errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(!file->dev) {
|
||||
r->_errno = ENODEV;
|
||||
return -1;
|
||||
@ -221,18 +220,9 @@ static int fs_dev_close_r (struct _reent *r, void *fd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static off_t fs_dev_seek_r (struct _reent *r, void* fd, off_t pos, int dir)
|
||||
static off_t fs_dev_seek_r (struct _reent *r, void *fd, off_t pos, int dir)
|
||||
{
|
||||
fs_dev_file_state_t *file = (fs_dev_file_state_t *)fd;
|
||||
|
||||
if(!r)
|
||||
return 0;
|
||||
|
||||
if(!file) {
|
||||
r->_errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(!file->dev) {
|
||||
r->_errno = ENODEV;
|
||||
return 0;
|
||||
@ -271,15 +261,6 @@ static off_t fs_dev_seek_r (struct _reent *r, void* fd, off_t pos, int dir)
|
||||
static ssize_t fs_dev_write_r (struct _reent *r, void *fd, const char *ptr, size_t len)
|
||||
{
|
||||
fs_dev_file_state_t *file = (fs_dev_file_state_t *)fd;
|
||||
|
||||
if(!r)
|
||||
return 0;
|
||||
|
||||
if(!file) {
|
||||
r->_errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(!file->dev) {
|
||||
r->_errno = ENODEV;
|
||||
return 0;
|
||||
@ -324,16 +305,7 @@ static ssize_t fs_dev_write_r (struct _reent *r, void *fd, const char *ptr, size
|
||||
|
||||
static ssize_t fs_dev_read_r (struct _reent *r, void *fd, char *ptr, size_t len)
|
||||
{
|
||||
if(!r)
|
||||
return 0;
|
||||
|
||||
fs_dev_file_state_t *file = (fs_dev_file_state_t *)fd;
|
||||
|
||||
if(!file) {
|
||||
r->_errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(!file->dev) {
|
||||
r->_errno = ENODEV;
|
||||
return 0;
|
||||
@ -362,7 +334,7 @@ static ssize_t fs_dev_read_r (struct _reent *r, void *fd, char *ptr, size_t len)
|
||||
}
|
||||
else if(result == 0)
|
||||
{
|
||||
/*! TODO: error on read_size > 0 */
|
||||
//! TODO: error on read_size > 0
|
||||
break;
|
||||
}
|
||||
else
|
||||
@ -380,15 +352,6 @@ static ssize_t fs_dev_read_r (struct _reent *r, void *fd, char *ptr, size_t len)
|
||||
static int fs_dev_fstat_r (struct _reent *r, void *fd, struct stat *st)
|
||||
{
|
||||
fs_dev_file_state_t *file = (fs_dev_file_state_t *)fd;
|
||||
|
||||
if(!r)
|
||||
return -1;
|
||||
|
||||
if(!file) {
|
||||
r->_errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(!file->dev) {
|
||||
r->_errno = ENODEV;
|
||||
return -1;
|
||||
@ -396,7 +359,7 @@ static int fs_dev_fstat_r (struct _reent *r, void *fd, struct stat *st)
|
||||
|
||||
OSLockMutex(file->dev->pMutex);
|
||||
|
||||
/* Zero out the stat buffer */
|
||||
// Zero out the stat buffer
|
||||
memset(st, 0, sizeof(struct stat));
|
||||
|
||||
fileStat_s stats;
|
||||
@ -412,7 +375,7 @@ static int fs_dev_fstat_r (struct _reent *r, void *fd, struct stat *st)
|
||||
st->st_blocks = (stats.size + 511) >> 9;
|
||||
st->st_nlink = 1;
|
||||
|
||||
/* Fill in the generic entry stats */
|
||||
// Fill in the generic entry stats
|
||||
st->st_dev = stats.id;
|
||||
st->st_uid = stats.owner_id;
|
||||
st->st_gid = stats.group_id;
|
||||
@ -427,54 +390,32 @@ static int fs_dev_fstat_r (struct _reent *r, void *fd, struct stat *st)
|
||||
static int fs_dev_ftruncate_r (struct _reent *r, void *fd, off_t len)
|
||||
{
|
||||
fs_dev_file_state_t *file = (fs_dev_file_state_t *)fd;
|
||||
|
||||
if(!r)
|
||||
return -1;
|
||||
|
||||
if(!file) {
|
||||
r->_errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(!file->dev) {
|
||||
r->_errno = ENODEV;
|
||||
return -1;
|
||||
}
|
||||
|
||||
r->_errno = ENOTSUP;
|
||||
/* TODO */
|
||||
// TODO
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int fs_dev_fsync_r (struct _reent *r, void *fd)
|
||||
{
|
||||
fs_dev_file_state_t *file = (fs_dev_file_state_t *)fd;
|
||||
|
||||
if(!r)
|
||||
return -1;
|
||||
|
||||
if(!file) {
|
||||
r->_errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(!file->dev) {
|
||||
r->_errno = ENODEV;
|
||||
return -1;
|
||||
}
|
||||
|
||||
r->_errno = ENOTSUP;
|
||||
/* TODO */
|
||||
// TODO
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int fs_dev_stat_r (struct _reent *r, const char *path, struct stat *st)
|
||||
{
|
||||
fs_dev_private_t *dev = fs_dev_get_device_data(path);
|
||||
|
||||
if(!r)
|
||||
return -1;
|
||||
|
||||
if(!dev) {
|
||||
r->_errno = ENODEV;
|
||||
return -1;
|
||||
@ -525,9 +466,6 @@ static int fs_dev_stat_r (struct _reent *r, const char *path, struct stat *st)
|
||||
|
||||
static int fs_dev_link_r (struct _reent *r, const char *existing, const char *newLink)
|
||||
{
|
||||
if(!r)
|
||||
return -1;
|
||||
|
||||
r->_errno = ENOTSUP;
|
||||
return -1;
|
||||
}
|
||||
@ -535,10 +473,6 @@ static int fs_dev_link_r (struct _reent *r, const char *existing, const char *ne
|
||||
static int fs_dev_unlink_r (struct _reent *r, const char *name)
|
||||
{
|
||||
fs_dev_private_t *dev = fs_dev_get_device_data(name);
|
||||
|
||||
if(!r)
|
||||
return -1;
|
||||
|
||||
if(!dev) {
|
||||
r->_errno = ENODEV;
|
||||
return -1;
|
||||
@ -570,10 +504,6 @@ static int fs_dev_unlink_r (struct _reent *r, const char *name)
|
||||
static int fs_dev_chdir_r (struct _reent *r, const char *name)
|
||||
{
|
||||
fs_dev_private_t *dev = fs_dev_get_device_data(name);
|
||||
|
||||
if(!r)
|
||||
return -1;
|
||||
|
||||
if(!dev) {
|
||||
r->_errno = ENODEV;
|
||||
return -1;
|
||||
@ -605,20 +535,11 @@ static int fs_dev_chdir_r (struct _reent *r, const char *name)
|
||||
static int fs_dev_rename_r (struct _reent *r, const char *oldName, const char *newName)
|
||||
{
|
||||
fs_dev_private_t *dev = fs_dev_get_device_data(oldName);
|
||||
|
||||
if(!r)
|
||||
return -1;
|
||||
|
||||
if(!dev) {
|
||||
r->_errno = ENODEV;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(!newName) {
|
||||
r->_errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
OSLockMutex(dev->pMutex);
|
||||
|
||||
char *real_oldpath = fs_dev_real_path(oldName, dev);
|
||||
@ -655,10 +576,6 @@ static int fs_dev_rename_r (struct _reent *r, const char *oldName, const char *n
|
||||
static int fs_dev_mkdir_r (struct _reent *r, const char *path, int mode)
|
||||
{
|
||||
fs_dev_private_t *dev = fs_dev_get_device_data(path);
|
||||
|
||||
if(!r)
|
||||
return -1;
|
||||
|
||||
if(!dev) {
|
||||
r->_errno = ENODEV;
|
||||
return -1;
|
||||
@ -690,10 +607,6 @@ static int fs_dev_mkdir_r (struct _reent *r, const char *path, int mode)
|
||||
static int fs_dev_chmod_r (struct _reent *r, const char *path, int mode)
|
||||
{
|
||||
fs_dev_private_t *dev = fs_dev_get_device_data(path);
|
||||
|
||||
if(!r)
|
||||
return -1;
|
||||
|
||||
if(!dev) {
|
||||
r->_errno = ENODEV;
|
||||
return -1;
|
||||
@ -725,20 +638,11 @@ static int fs_dev_chmod_r (struct _reent *r, const char *path, int mode)
|
||||
static int fs_dev_statvfs_r (struct _reent *r, const char *path, struct statvfs *buf)
|
||||
{
|
||||
fs_dev_private_t *dev = fs_dev_get_device_data(path);
|
||||
|
||||
if(!r)
|
||||
return -1;
|
||||
|
||||
if(!dev) {
|
||||
r->_errno = ENODEV;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(!buf) {
|
||||
r->_errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
OSLockMutex(dev->pMutex);
|
||||
|
||||
// Zero out the stat buffer
|
||||
@ -798,20 +702,11 @@ static int fs_dev_statvfs_r (struct _reent *r, const char *path, struct statvfs
|
||||
static DIR_ITER *fs_dev_diropen_r (struct _reent *r, DIR_ITER *dirState, const char *path)
|
||||
{
|
||||
fs_dev_private_t *dev = fs_dev_get_device_data(path);
|
||||
|
||||
if(!r)
|
||||
return NULL;
|
||||
|
||||
if(!dev) {
|
||||
r->_errno = ENODEV;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(!dirState) {
|
||||
r->_errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fs_dev_dir_entry_t *dirIter = (fs_dev_dir_entry_t *)dirState->dirStruct;
|
||||
|
||||
OSLockMutex(dev->pMutex);
|
||||
@ -845,18 +740,7 @@ static DIR_ITER *fs_dev_diropen_r (struct _reent *r, DIR_ITER *dirState, const c
|
||||
|
||||
static int fs_dev_dirclose_r (struct _reent *r, DIR_ITER *dirState)
|
||||
{
|
||||
fs_dev_dir_entry_t *dirIter;
|
||||
|
||||
if(!r)
|
||||
return -1;
|
||||
|
||||
if(!dirState) {
|
||||
r->_errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
dirIter = (fs_dev_dir_entry_t *)dirState->dirStruct;
|
||||
|
||||
fs_dev_dir_entry_t *dirIter = (fs_dev_dir_entry_t *)dirState->dirStruct;
|
||||
if(!dirIter->dev) {
|
||||
r->_errno = ENODEV;
|
||||
return -1;
|
||||
@ -878,18 +762,7 @@ static int fs_dev_dirclose_r (struct _reent *r, DIR_ITER *dirState)
|
||||
|
||||
static int fs_dev_dirreset_r (struct _reent *r, DIR_ITER *dirState)
|
||||
{
|
||||
fs_dev_dir_entry_t *dirIter;
|
||||
|
||||
if(!r)
|
||||
return -1;
|
||||
|
||||
if(!dirState) {
|
||||
r->_errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
dirIter = (fs_dev_dir_entry_t *)dirState->dirStruct;
|
||||
|
||||
fs_dev_dir_entry_t *dirIter = (fs_dev_dir_entry_t *)dirState->dirStruct;
|
||||
if(!dirIter->dev) {
|
||||
r->_errno = ENODEV;
|
||||
return -1;
|
||||
@ -911,18 +784,7 @@ static int fs_dev_dirreset_r (struct _reent *r, DIR_ITER *dirState)
|
||||
|
||||
static int fs_dev_dirnext_r (struct _reent *r, DIR_ITER *dirState, char *filename, struct stat *st)
|
||||
{
|
||||
fs_dev_dir_entry_t *dirIter;
|
||||
|
||||
if(!r)
|
||||
return -1;
|
||||
|
||||
if(!dirState) {
|
||||
r->_errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
dirIter = (fs_dev_dir_entry_t *)dirState->dirStruct;
|
||||
|
||||
fs_dev_dir_entry_t *dirIter = (fs_dev_dir_entry_t *)dirState->dirStruct;
|
||||
if(!dirIter->dev) {
|
||||
r->_errno = ENODEV;
|
||||
return -1;
|
||||
@ -1002,7 +864,7 @@ static int fs_dev_add_device (const char *name, const char *mount_path, int fsaF
|
||||
int i;
|
||||
|
||||
// Sanity check
|
||||
if (!name || !mount_path) {
|
||||
if (!name) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
@ -1072,9 +934,6 @@ static int fs_dev_remove_device (const char *path)
|
||||
char name[128] = {0};
|
||||
int i;
|
||||
|
||||
if(!path)
|
||||
return -1;
|
||||
|
||||
// Get the device name from the path
|
||||
strncpy(name, path, 127);
|
||||
strtok(name, ":/");
|
@ -141,7 +141,7 @@ static bool IOSUHAX_sdio_shutdown(void)
|
||||
|
||||
static bool IOSUHAX_sdio_readSectors(uint32_t sector, uint32_t numSectors, void* buffer)
|
||||
{
|
||||
if(!IOSUHAX_sdio_isInserted() || !buffer)
|
||||
if(!IOSUHAX_sdio_isInserted())
|
||||
return false;
|
||||
|
||||
int res = IOSUHAX_FSA_RawRead(fsaFdSd, buffer, 512, numSectors, sector, sdioFd);
|
||||
@ -155,7 +155,7 @@ static bool IOSUHAX_sdio_readSectors(uint32_t sector, uint32_t numSectors, void*
|
||||
|
||||
static bool IOSUHAX_sdio_writeSectors(uint32_t sector, uint32_t numSectors, const void* buffer)
|
||||
{
|
||||
if(!IOSUHAX_sdio_isInserted() || !buffer)
|
||||
if(!IOSUHAX_sdio_isInserted())
|
||||
return false;
|
||||
|
||||
int res = IOSUHAX_FSA_RawWrite(fsaFdSd, buffer, 512, numSectors, sector, sdioFd);
|
||||
@ -223,7 +223,7 @@ static bool IOSUHAX_usb_shutdown(void)
|
||||
|
||||
static bool IOSUHAX_usb_readSectors(uint32_t sector, uint32_t numSectors, void* buffer)
|
||||
{
|
||||
if(!IOSUHAX_usb_isInserted() || !buffer)
|
||||
if(!IOSUHAX_usb_isInserted())
|
||||
return false;
|
||||
|
||||
int res = IOSUHAX_FSA_RawRead(fsaFdUsb, buffer, 512, numSectors, sector, usbFd);
|
||||
@ -237,7 +237,7 @@ static bool IOSUHAX_usb_readSectors(uint32_t sector, uint32_t numSectors, void*
|
||||
|
||||
static bool IOSUHAX_usb_writeSectors(uint32_t sector, uint32_t numSectors, const void* buffer)
|
||||
{
|
||||
if(!IOSUHAX_usb_isInserted() || !buffer)
|
||||
if(!IOSUHAX_usb_isInserted())
|
||||
return false;
|
||||
|
||||
int res = IOSUHAX_FSA_RawWrite(fsaFdUsb, buffer, 512, numSectors, sector, usbFd);
|
28
deps/libiosuhax/source/os_functions.h
vendored
Normal file
28
deps/libiosuhax/source/os_functions.h
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
#ifndef __OS_FUNCTIONS_H_
|
||||
#define __OS_FUNCTIONS_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define OS_MUTEX_SIZE 44
|
||||
|
||||
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
//! Mutex functions
|
||||
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
extern void OSInitMutex(void* mutex);
|
||||
extern void OSLockMutex(void* mutex);
|
||||
extern void OSUnlockMutex(void* mutex);
|
||||
|
||||
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
//! IOS function
|
||||
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
extern int IOS_Ioctl(int fd, unsigned int request, void *input_buffer,unsigned int input_buffer_len, void *output_buffer, unsigned int output_buffer_len);
|
||||
extern int IOS_Open(char *path, unsigned int mode);
|
||||
extern int IOS_Close(int fd);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __OS_FUNCTIONS_H_
|
@ -1515,9 +1515,9 @@ DEPENDENCIES
|
||||
#endif
|
||||
|
||||
#ifdef WANT_IOSUHAX
|
||||
#include "../deps/libiosuhax/iosuhax.c"
|
||||
#include "../deps/libiosuhax/iosuhax_devoptab.c"
|
||||
#include "../deps/libiosuhax/iosuhax_disc_interface.c"
|
||||
#include "../deps/libiosuhax/source/iosuhax.c"
|
||||
#include "../deps/libiosuhax/source/iosuhax_devoptab.c"
|
||||
#include "../deps/libiosuhax/source/iosuhax_disc_interface.c"
|
||||
#endif
|
||||
|
||||
/*============================================================
|
||||
|
@ -22,6 +22,9 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#if defined(WIIU)
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
|
||||
#include <file/nbio.h>
|
||||
#include <encodings/utf.h>
|
||||
@ -130,8 +133,14 @@ static void *nbio_stdio_open(const char * filename, unsigned mode)
|
||||
|
||||
handle->mode = mode;
|
||||
|
||||
#if defined(WIIU)
|
||||
/* hit the aligned-buffer fast path on Wii U */
|
||||
if (len)
|
||||
buf = memalign(0x40, (size_t)len);
|
||||
#else
|
||||
if (len)
|
||||
buf = malloc((size_t)len);
|
||||
#endif
|
||||
|
||||
if (len && !buf)
|
||||
goto error;
|
||||
|
@ -62,6 +62,9 @@
|
||||
# include <sys/dirent.h>
|
||||
# include <orbisFile.h>
|
||||
# endif
|
||||
# if defined(WIIU)
|
||||
# include <malloc.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <fcntl.h>
|
||||
@ -447,6 +450,14 @@ libretro_vfs_implementation_file *retro_vfs_file_open_impl(
|
||||
if (stream->fp)
|
||||
setvbuf(stream->fp, stream->buf, _IOFBF, 0x10000);
|
||||
}
|
||||
#elif defined(WIIU)
|
||||
if (stream->scheme != VFS_SCHEME_CDROM)
|
||||
{
|
||||
const int bufsize = 128*1024;
|
||||
stream->buf = (char*)memalign(0x40, bufsize);
|
||||
if (stream->fp)
|
||||
setvbuf(stream->fp, stream->buf, _IOFBF, bufsize);
|
||||
}
|
||||
#elif !defined(PSP)
|
||||
if (stream->scheme != VFS_SCHEME_CDROM)
|
||||
{
|
||||
|
@ -279,47 +279,56 @@ static ssize_t sd_fat_write_r (struct _reent *r, void* fd, const char *ptr, size
|
||||
|
||||
OSLockMutex(file->dev->pMutex);
|
||||
|
||||
size_t len_aligned = FS_ALIGN(len);
|
||||
if(len_aligned > 0x4000)
|
||||
len_aligned = 0x4000;
|
||||
|
||||
unsigned char *tmpBuf = (unsigned char *)memalign(FS_ALIGNMENT, len_aligned);
|
||||
if(!tmpBuf) {
|
||||
r->_errno = ENOMEM;
|
||||
OSUnlockMutex(file->dev->pMutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t done = 0;
|
||||
|
||||
while(done < len)
|
||||
{
|
||||
size_t write_size = (len_aligned < (len - done)) ? len_aligned : (len - done);
|
||||
memcpy(tmpBuf, ptr + done, write_size);
|
||||
|
||||
int result = FSWriteFile(file->dev->pClient, file->dev->pCmd, tmpBuf, 0x01, write_size, file->fd, 0, -1);
|
||||
#if 0
|
||||
FSFlushFile(file->dev->pClient, file->dev->pCmd, file->fd, -1);
|
||||
#endif
|
||||
if(result < 0)
|
||||
{
|
||||
/* fast path: buffer is already correctly aligned */
|
||||
if (!((uintptr_t)ptr & (FS_ALIGNMENT-1))) {
|
||||
int result = FSWriteFile(file->dev->pClient, file->dev->pCmd, (uint8_t*)ptr, 1, len, file->fd, 0, -1);
|
||||
if(result < 0) {
|
||||
r->_errno = result;
|
||||
break;
|
||||
}
|
||||
else if(result == 0)
|
||||
{
|
||||
if(write_size > 0)
|
||||
done = 0;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
done += result;
|
||||
} else {
|
||||
done = result;
|
||||
file->pos += result;
|
||||
}
|
||||
} else {
|
||||
size_t len_aligned = FS_ALIGN(len);
|
||||
if(len_aligned > 0x4000)
|
||||
len_aligned = 0x4000;
|
||||
|
||||
unsigned char *tmpBuf = (unsigned char *)memalign(FS_ALIGNMENT, len_aligned);
|
||||
if(!tmpBuf) {
|
||||
r->_errno = ENOMEM;
|
||||
OSUnlockMutex(file->dev->pMutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
while(done < len)
|
||||
{
|
||||
size_t write_size = (len_aligned < (len - done)) ? len_aligned : (len - done);
|
||||
memcpy(tmpBuf, ptr + done, write_size);
|
||||
|
||||
int result = FSWriteFile(file->dev->pClient, file->dev->pCmd, tmpBuf, 0x01, write_size, file->fd, 0, -1);
|
||||
if(result < 0)
|
||||
{
|
||||
r->_errno = result;
|
||||
break;
|
||||
}
|
||||
else if(result == 0)
|
||||
{
|
||||
if(write_size > 0)
|
||||
done = 0;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
done += result;
|
||||
file->pos += result;
|
||||
}
|
||||
}
|
||||
|
||||
free(tmpBuf);
|
||||
}
|
||||
|
||||
free(tmpBuf);
|
||||
OSUnlockMutex(file->dev->pMutex);
|
||||
return done;
|
||||
}
|
||||
@ -340,44 +349,56 @@ static ssize_t sd_fat_read_r (struct _reent *r, void* fd, char *ptr, size_t len)
|
||||
|
||||
OSLockMutex(file->dev->pMutex);
|
||||
|
||||
size_t len_aligned = FS_ALIGN(len);
|
||||
if(len_aligned > 0x4000)
|
||||
len_aligned = 0x4000;
|
||||
|
||||
unsigned char *tmpBuf = (unsigned char *)memalign(FS_ALIGNMENT, len_aligned);
|
||||
if(!tmpBuf) {
|
||||
r->_errno = ENOMEM;
|
||||
OSUnlockMutex(file->dev->pMutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t done = 0;
|
||||
|
||||
while(done < len)
|
||||
{
|
||||
size_t read_size = (len_aligned < (len - done)) ? len_aligned : (len - done);
|
||||
|
||||
int result = FSReadFile(file->dev->pClient, file->dev->pCmd, tmpBuf, 0x01, read_size, file->fd, 0, -1);
|
||||
if(result < 0)
|
||||
{
|
||||
/* fast path: buffer is already correctly aligned */
|
||||
if (!((uintptr_t)ptr & (FS_ALIGNMENT-1))) {
|
||||
int result = FSReadFile(file->dev->pClient, file->dev->pCmd, (uint8_t*)ptr, 1, len, file->fd, 0, -1);
|
||||
if(result < 0) {
|
||||
r->_errno = result;
|
||||
done = 0;
|
||||
break;
|
||||
}
|
||||
else if(result == 0)
|
||||
{
|
||||
/*! TODO: error on read_size > 0 */
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(ptr + done, tmpBuf, read_size);
|
||||
done += result;
|
||||
} else {
|
||||
done = result;
|
||||
file->pos += result;
|
||||
}
|
||||
} else {
|
||||
size_t len_aligned = FS_ALIGN(len);
|
||||
if(len_aligned > 0x4000)
|
||||
len_aligned = 0x4000;
|
||||
|
||||
unsigned char *tmpBuf = (unsigned char *)memalign(FS_ALIGNMENT, len_aligned);
|
||||
if(!tmpBuf) {
|
||||
r->_errno = ENOMEM;
|
||||
OSUnlockMutex(file->dev->pMutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
while(done < len)
|
||||
{
|
||||
size_t read_size = (len_aligned < (len - done)) ? len_aligned : (len - done);
|
||||
|
||||
int result = FSReadFile(file->dev->pClient, file->dev->pCmd, tmpBuf, 0x01, read_size, file->fd, 0, -1);
|
||||
if(result < 0)
|
||||
{
|
||||
r->_errno = result;
|
||||
done = 0;
|
||||
break;
|
||||
}
|
||||
else if(result == 0)
|
||||
{
|
||||
/*! TODO: error on read_size > 0 */
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(ptr + done, tmpBuf, read_size);
|
||||
done += result;
|
||||
file->pos += result;
|
||||
}
|
||||
}
|
||||
|
||||
free(tmpBuf);
|
||||
}
|
||||
|
||||
free(tmpBuf);
|
||||
OSUnlockMutex(file->dev->pMutex);
|
||||
return done;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user