diff --git a/archive.c b/archive.c index efb78a7..28f4d3e 100644 --- a/archive.c +++ b/archive.c @@ -201,18 +201,42 @@ int extractArchivePath(char *src, char *dst, FileProcessParam *param) { void *buf = malloc(TRANSFER_SIZE); - int read; - while ((read = archiveFileRead(fdsrc, buf, TRANSFER_SIZE)) > 0) { - int res = sceIoWrite(fddst, buf, read); - if (res < 0) { + uint64_t seek = 0; + + while (1) { + int read = archiveFileRead(fdsrc, buf, TRANSFER_SIZE); + if (read < 0) { free(buf); sceIoClose(fddst); archiveFileClose(fdsrc); - return res; + return read; } + if (read == 0) + break; + + int written = sceIoWrite(fddst, buf, read); + if (written == SCE_ERROR_ERRNO_ENODEV) { + fddst = sceIoOpen(dst_path, SCE_O_WRONLY | SCE_O_CREAT, 0777); + if (fddst >= 0) { + sceIoLseek(fddst, seek, SCE_SEEK_SET); + written = sceIoWrite(fddst, buf, read); + } + } + + if (written != read) { + free(buf); + + sceIoClose(fddst); + archiveFileClose(fdsrc); + + return (written < 0) ? written : -1; + } + + seek += written; + if (param) { if (param->value) (*param->value) += read; diff --git a/file.c b/file.c index 76ee21f..8594a61 100644 --- a/file.c +++ b/file.c @@ -108,12 +108,32 @@ int getFileSha1(char *pInputFileName, uint8_t *pSha1Out, FileProcessParam *param // Open up the buffer for copying data into void *buf = malloc(TRANSFER_SIZE); - int read; + uint64_t seek = 0; // Actually take the SHA1 sum - while ((read = sceIoRead(fd, buf, TRANSFER_SIZE)) > 0) { + while (1) { + int read = sceIoRead(fd, buf, TRANSFER_SIZE); + if (read == SCE_ERROR_ERRNO_ENODEV) { + fd = sceIoOpen(pInputFileName, SCE_O_RDONLY, 0); + if (fd >= 0) { + sceIoLseek(fd, seek, SCE_SEEK_SET); + read = sceIoRead(fd, buf, TRANSFER_SIZE); + } + } + + if (read < 0) { + free(buf); + sceIoClose(fd); + return read; + } + + if (read == 0) + break; + sha1_update(&ctx, buf, read); + seek += read; + if (param) { // Defined in io_process.c, check to make sure pointer isn't null before incrementing if (param->value) @@ -320,18 +340,50 @@ int copyFile(char *src_path, char *dst_path, FileProcessParam *param) { void *buf = malloc(TRANSFER_SIZE); - int read; - while ((read = sceIoRead(fdsrc, buf, TRANSFER_SIZE)) > 0) { - int res = sceIoWrite(fddst, buf, read); - if (res < 0) { + uint64_t seek = 0; + + while (1) { + int read = sceIoRead(fdsrc, buf, TRANSFER_SIZE); + if (read == SCE_ERROR_ERRNO_ENODEV) { + fdsrc = sceIoOpen(src_path, SCE_O_RDONLY, 0); + if (fdsrc >= 0) { + sceIoLseek(fdsrc, seek, SCE_SEEK_SET); + read = sceIoRead(fdsrc, buf, TRANSFER_SIZE); + } + } + + if (read < 0) { free(buf); sceIoClose(fddst); sceIoClose(fdsrc); - return res; + return read; } + if (read == 0) + break; + + int written = sceIoWrite(fddst, buf, read); + if (written == SCE_ERROR_ERRNO_ENODEV) { + fddst = sceIoOpen(dst_path, SCE_O_WRONLY | SCE_O_CREAT, 0777); + if (fddst >= 0) { + sceIoLseek(fddst, seek, SCE_SEEK_SET); + written = sceIoWrite(fddst, buf, read); + } + } + + if (written != read) { + free(buf); + + sceIoClose(fddst); + sceIoClose(fdsrc); + + return (written < 0) ? written : -1; + } + + seek += written; + if (param) { if (param->value) (*param->value) += read; @@ -518,7 +570,7 @@ int movePath(char *src_path, char *dst_path, int flags, FileProcessParam *param) } while (res > 0); sceIoDclose(dfd); - + // Integrated, now remove this directory sceIoRmdir(src_path); } diff --git a/functions.h b/functions.h index 9b3e8a6..4aa9d58 100644 --- a/functions.h +++ b/functions.h @@ -20,6 +20,7 @@ #define __FUNCTIONS_H__ #define SCE_ERROR_ERRNO_EEXIST 0x80010011 +#define SCE_ERROR_ERRNO_ENODEV 0x80010013 typedef struct { SceUInt size; diff --git a/minizip/ioapi.c b/minizip/ioapi.c index 28e22f6..4b65512 100644 --- a/minizip/ioapi.c +++ b/minizip/ioapi.c @@ -18,6 +18,8 @@ #include "ioapi.h" +#define SCE_ERROR_ERRNO_ENODEV 0x80010013 + voidpf call_zopen64 (const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode) { if (pfilefunc->zfile_func64.zopen64_file != NULL) @@ -83,18 +85,22 @@ static int ZCALLBACK ferror_file_func OF((voidpf opaque, voidpf stream)); typedef struct { SceUID fd; + int mode_fopen; + SceOff offset; int error; int filenameLength; void *filename; } FILE_IOPOSIX; -static voidpf file_build_ioposix(SceUID fd, const char *filename) +static voidpf file_build_ioposix(SceUID fd, const char *filename, int mode_fopen) { FILE_IOPOSIX *ioposix = NULL; if (fd < 0) return NULL; ioposix = (FILE_IOPOSIX*)malloc(sizeof(FILE_IOPOSIX)); ioposix->fd = fd; + ioposix->mode_fopen = mode_fopen; + ioposix->offset = 0; ioposix->error = 0; ioposix->filenameLength = strlen(filename) + 1; ioposix->filename = (char*)malloc(ioposix->filenameLength * sizeof(char)); @@ -118,7 +124,7 @@ static voidpf ZCALLBACK fopen_file_func (voidpf opaque, const char* filename, in if ((filename != NULL) && (mode_fopen != 0)) { fd = sceIoOpen(filename, mode_fopen, 0777); - return file_build_ioposix(fd, filename); + return file_build_ioposix(fd, filename, mode_fopen); } return NULL; @@ -158,6 +164,16 @@ static uLong ZCALLBACK fread_file_func (voidpf opaque, voidpf stream, void* buf, ioposix = (FILE_IOPOSIX*)stream; ret = (uLong)sceIoRead(ioposix->fd, buf, (size_t)size); ioposix->error = (int)ret; + if (ioposix->error == SCE_ERROR_ERRNO_ENODEV) { + ioposix->fd = sceIoOpen(ioposix->filename, ioposix->mode_fopen, 0777); + if (ioposix->fd >= 0) { + sceIoLseek(ioposix->fd, ioposix->offset, SCE_SEEK_SET); + ret = (uLong)sceIoRead(ioposix->fd, buf, (size_t)size); + ioposix->error = (int)ret; + } + } + if (ioposix->error == 0) + ioposix->offset += ret; return ret; } @@ -170,6 +186,16 @@ static uLong ZCALLBACK fwrite_file_func (voidpf opaque, voidpf stream, const voi ioposix = (FILE_IOPOSIX*)stream; ret = (uLong)sceIoWrite(ioposix->fd, buf, (size_t)size); ioposix->error = (int)ret; + if (ioposix->error == SCE_ERROR_ERRNO_ENODEV) { + ioposix->fd = sceIoOpen(ioposix->filename, ioposix->mode_fopen, 0777); + if (ioposix->fd >= 0) { + sceIoLseek(ioposix->fd, ioposix->offset, SCE_SEEK_SET); + ret = (uLong)sceIoWrite(ioposix->fd, buf, (size_t)size); + ioposix->error = (int)ret; + } + } + if (ioposix->error == 0) + ioposix->offset += ret; return ret; } @@ -182,6 +208,14 @@ static long ZCALLBACK ftell_file_func (voidpf opaque, voidpf stream) ioposix = (FILE_IOPOSIX*)stream; ret = (long)sceIoLseek32(ioposix->fd, 0, SCE_SEEK_CUR); ioposix->error = (int)ret; + if (ioposix->error == SCE_ERROR_ERRNO_ENODEV) { + ioposix->fd = sceIoOpen(ioposix->filename, ioposix->mode_fopen, 0777); + if (ioposix->fd >= 0) { + sceIoLseek32(ioposix->fd, ioposix->offset, SCE_SEEK_SET); + ret = (long)sceIoLseek32(ioposix->fd, 0, SCE_SEEK_CUR); + ioposix->error = (int)ret; + } + } return ret; } @@ -194,6 +228,14 @@ static ZPOS64_T ZCALLBACK ftell64_file_func (voidpf opaque, voidpf stream) ioposix = (FILE_IOPOSIX*)stream; ret = (ZPOS64_T)sceIoLseek(ioposix->fd, 0, SCE_SEEK_CUR); ioposix->error = (int)ret; + if (ioposix->error == SCE_ERROR_ERRNO_ENODEV) { + ioposix->fd = sceIoOpen(ioposix->filename, ioposix->mode_fopen, 0777); + if (ioposix->fd >= 0) { + sceIoLseek(ioposix->fd, ioposix->offset, SCE_SEEK_SET); + ret = (long)sceIoLseek(ioposix->fd, 0, SCE_SEEK_CUR); + ioposix->error = (int)ret; + } + } return ret; } @@ -221,8 +263,19 @@ static long ZCALLBACK fseek_file_func (voidpf opaque, voidpf stream, uLong offse default: return -1; } - if (sceIoLseek32(ioposix->fd, offset, fseek_origin) < 0) + int res = sceIoLseek32(ioposix->fd, offset, fseek_origin); + if (res == SCE_ERROR_ERRNO_ENODEV) { + ioposix->fd = sceIoOpen(ioposix->filename, ioposix->mode_fopen, 0777); + if (ioposix->fd >= 0) { + sceIoLseek(ioposix->fd, ioposix->offset, SCE_SEEK_SET); + res = sceIoLseek32(ioposix->fd, offset, fseek_origin); + } + } + if (res < 0) { ret = -1; + } else { + ioposix->offset = (SceOff)res; + } return ret; } @@ -250,8 +303,19 @@ static long ZCALLBACK fseek64_file_func (voidpf opaque, voidpf stream, ZPOS64_T default: return -1; } - if (sceIoLseek(ioposix->fd, offset, fseek_origin) < 0) + SceOff res = sceIoLseek(ioposix->fd, offset, fseek_origin); + if ((int)res == SCE_ERROR_ERRNO_ENODEV) { + ioposix->fd = sceIoOpen(ioposix->filename, ioposix->mode_fopen, 0777); + if (ioposix->fd >= 0) { + sceIoLseek(ioposix->fd, ioposix->offset, SCE_SEEK_SET); + res = sceIoLseek(ioposix->fd, offset, fseek_origin); + } + } + if (res < 0) { ret = -1; + } else { + ioposix->offset = res; + } return ret; } @@ -266,6 +330,14 @@ static int ZCALLBACK fclose_file_func (voidpf opaque, voidpf stream) free(ioposix->filename); ret = sceIoClose(ioposix->fd); ioposix->error = ret; + if (ioposix->error == SCE_ERROR_ERRNO_ENODEV) { + ioposix->fd = sceIoOpen(ioposix->filename, ioposix->mode_fopen, 0777); + if (ioposix->fd >= 0) { + sceIoLseek(ioposix->fd, ioposix->offset, SCE_SEEK_SET); + ret = sceIoClose(ioposix->fd); + ioposix->error = ret; + } + } free(ioposix); return ret; }