static void free_handle(int fh) { if(FD_OK(fh)) __av_dtable[fh].isvirtual = 0; real_close(fh, 1); }
File::~File() { DPRINTF("File destructor.\n"); if (FD_OK(fd)) this->close(); }
int File::open(const char *path, int flags) { if (FD_OK(fd)) this->close(); fd = open_file(path, flags); if (!FD_OK(fd)) return -1; // multi part int flen = strlen(path)-6; if(flen < 0) is_multipart = 0; else is_multipart = (strstr(path + flen, ".iso.0") != NULL || strstr(path + flen, ".ISO.0") != NULL); if(!is_multipart) return 0; char *filepath = (char *)malloc(strlen(path)+2); strcpy(filepath, path); file_stat_t st; fstat_file(fd, &st); part_size = st.file_size; is_multipart = 1; // count parts for(int i = 1; i < 64; i++) { filepath[flen+4] = 0; sprintf(filepath, "%s.%i", filepath, i); fp[i] = open_file(filepath, flags); if (!FD_OK(fp[i])) break; is_multipart++; } fp[0] = fd; free(filepath); return 0; }
static int parse_param_sfo(file_t fd, const char *field, char *title_name) { if (FD_OK(fd)) { unsigned len, pos, str; unsigned char *mem = NULL; len = seek_file(fd, 0, SEEK_END); mem = (unsigned char *) malloc(len + 16); if (!mem) { close_file(fd); return -2; } memset(mem, 0, len + 16); seek_file(fd, 0, SEEK_SET); read_file(fd, mem, len); close_file(fd); str = (mem[8] + (mem[9] << 8)); pos = (mem[0xc] + (mem[0xd] << 8)); int indx = 0; while (str < len) { if (mem[str] == 0) break; if (!strcmp((char *) &mem[str], field)) { strncpy(title_name, (char *) &mem[pos], 63); free(mem); return 0; } while (mem[str]) str++; str++; pos += (mem[0x1c + indx] + (mem[0x1d + indx] << 8)); indx += 16; } if (mem) free(mem); } return -1; }
static int virt_close(int fd, int undersc) { int res; if(!FD_OK(fd) || !ISVIRTUAL(fd)) res = real_close(fd, undersc); else { int errnosave = errno; res = cmd_close(SERVERFH(fd)); real_close(__av_dtable[fd].holderfd, 1); free_handle(fd); if(res < 0) errno = -res, res = -1; else errno = errnosave; } return res; }
static bool get_title_id(const char *dir, char *title_id) { char sfo_path[MAX_PATH]; file_t fd; snprintf(sfo_path, sizeof(sfo_path)-1, "%s/PS3_GAME/PARAM.SFO", dir); fd = open_file(sfo_path, O_RDONLY); if (!FD_OK(fd)) { fprintf(stderr, "Cannot find %s\n", sfo_path); return false; } if (parse_param_sfo(fd, "TITLE_ID", title_id) != 0) { fprintf(stderr, "TITLE_ID not found\n"); return false; } return true; }
static int get_handle() { int fh = -1; char dummyfile[64]; int numtries; for(numtries = 0; numtries < 10; numtries++) { strcpy(dummyfile, "/tmp/.avfs_dummyfile_XXXXXX"); mktemp(dummyfile); if(dummyfile[0] != '\0') { fh = real_open(dummyfile, O_RDONLY | O_CREAT | O_EXCL, 0600, 1, 1, 0); real_unlink(dummyfile); } if(fh != -1) break; } if(fh == -1) return -EIO; if(!FD_OK(fh)) { real_close(fh, 1); return -EIO; } if(ISVIRTUAL(fh)) { real_close(fh, 1); __av_dtable[fh].isvirtual = 0; return -EFAULT; } fcntl(fh, F_SETFD, FD_CLOEXEC); __av_dtable[fh].isvirtual = 1; return fh; }
ssize_t VIsoFile::read(void *buf, size_t nbyte) { DirList *dirList; uint64_t remaining, to_read; uint64_t r; uint8_t *p; if (!fsBuf) return -1; remaining = nbyte; r = 0; p = (uint8_t *)buf; if (vFilePtr >= totalSize || remaining == 0) { return 0; } else if (vFilePtr < 0) { return -1; } if (vFilePtr < fsBufSize) { // Read FS structure from RAM to_read = MIN(fsBufSize-vFilePtr, remaining); memcpy(p, fsBuf+vFilePtr, to_read); remaining -= to_read; r += to_read; p += to_read; vFilePtr += to_read; } if (remaining == 0 || vFilePtr >= totalSize) return r; if (vFilePtr < padAreaStart) { // Read from file(s) dirList = rootList; while (dirList) { FileList *fileList = dirList->fileList; while (fileList) { uint64_t fStart = (uint64_t)fsBufSize + (uint64_t)fileList->rlba * 0x800; uint64_t fEnd = fStart + fileList->size; uint64_t fEndSector = ((fEnd+0x7ffULL)&~0x7ffULL); if (vFilePtr >= fStart && vFilePtr < fEndSector) { if (fileList->multipart) { fprintf(stderr, "Sorry no support for 666 files. I have the feeling that your game is about to crash ^_^\n"); return r; } if (vFilePtr < fEnd) { file_t fd; ssize_t this_r; to_read = MIN(fileList->size-(vFilePtr-fStart), remaining); fd = open_file(fileList->path, O_RDONLY); if (!FD_OK(fd)) { fprintf(stderr, "VISO: file %s cannot be opened!\n", fileList->path); return r; } seek_file(fd, vFilePtr-fStart, SEEK_SET); this_r = read_file(fd, p, to_read); close_file(fd); if (this_r < 0) { fprintf(stderr, "VISO: read_file failed on %s\n", fileList->path); return r; } if (this_r != to_read) { fprintf(stderr, "VISO: read on file %s returned less data than expected (file modified?)\n", fileList->path); return r; } remaining -= to_read; r += to_read; p += to_read; vFilePtr += to_read; } if (remaining > 0 && fEnd != fEndSector) { // This is a zero area after the file to fill the sector to_read = MIN((fEndSector-fEnd)-(vFilePtr-fEnd), remaining); memset(p, 0, to_read); remaining -= to_read; r += to_read; p += to_read; vFilePtr += to_read; } if (remaining == 0) return r; } fileList = fileList->next; } dirList = dirList->next; } } if (vFilePtr >= padAreaStart && vFilePtr < totalSize) { // Pad at the end to_read = MIN(padAreaSize-(vFilePtr-padAreaStart), remaining); memset(p, 0, to_read); remaining -= to_read; r += to_read; p += to_read; vFilePtr += to_read; } return r; }