Added reopening for suspend/resume enodev bug.

This commit is contained in:
TheFloW 2016-09-12 20:36:07 +02:00
parent d03f9623a1
commit 90a2e5fb73
4 changed files with 166 additions and 17 deletions

View File

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

68
file.c
View File

@ -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);
}

View File

@ -20,6 +20,7 @@
#define __FUNCTIONS_H__
#define SCE_ERROR_ERRNO_EEXIST 0x80010011
#define SCE_ERROR_ERRNO_ENODEV 0x80010013
typedef struct {
SceUInt size;

View File

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