static void hddUpdateInfo() { iox_dirent_t infoDirEnt; int rv; int hddFd, hddUsed = 0; hddSize = fileXioDevctl("hdd0:", HDDCTL_TOTAL_SECTORS, NULL, 0, NULL, 0) * 512 / 1024 / 1024; /* This seems to give in-accurate results fileXioDevctl("hdd0:", HDDCTL_FREE_SECTORS, NULL, 0, &rv, 4); hddFree = rv * 512 / 1024 / 1024; */ hddFd = fileXioDopen("hdd0:"); if(hddFd < 0) // For when a HDD is not connected! return; rv = fileXioDread(hddFd, &infoDirEnt); while(rv > 0) { if(infoDirEnt.stat.mode != FS_TYPE_EMPTY) hddUsed += infoDirEnt.stat.size * 512 / 1024 / 1024; rv = fileXioDread(hddFd, &infoDirEnt); } fileXioDclose(hddFd); hddFree = hddSize - hddUsed; hddMaxPartitionSize = fileXioDevctl("hdd0:", HDDCTL_MAX_SECTORS, NULL, 0, NULL, 0) * 512 / 1024 / 1024; hddStatusCurrent = 1; }
int AsyncFio::dread(int fd, iox_dirent_t *dest) { int res; WaitSema(_ioSema); checkSync(); fileXioDread(fd, dest); fileXioWaitAsync(FXIO_WAIT, &res); SignalSema(_ioSema); return res; }
void list_path(char *path, list_t *list) { int fd; int n = 0; iox_dirent_t buf; if(!strncmp(path,"cdfs:",5)) { CDVD_FlushCache(); } // Add fake .. directory entry add_reg_entry(list->entries, "..", n++); // Try to open the path if((fd=fileXioDopen(path)) < 0) { list->num = n; return; } else { // Add directories first while(fileXioDread(fd, &buf) > 0) { if(buf.stat.mode & FIO_S_IFDIR && (!strcmp(buf.name,".") || !strcmp(buf.name,".."))) continue; if(buf.stat.mode & FIO_S_IFDIR) { add_dir_entry(list->entries, buf.name, n++); } if (buf.stat.mode & FIO_S_IFREG) { add_reg_entry(list->entries, buf.name, n++); } // Prevent overflowing the list if (n >= list->size) { break; } } list->num = n; fileXioDclose(fd); } }
void list_partitions(list_t *list) { iox_dirent_t hddEnt; int hddFd; int n = 1; printf("listing partitions\n"); if((hddFd=fileXioDopen("hdd0:")) < 0) { list->num = n; return; } while(fileXioDread(hddFd, &hddEnt) > 0) { if((hddEnt.stat.attr != ATTR_MAIN_PARTITION) || (hddEnt.stat.mode != FS_TYPE_PFS)) continue; //Patch this to see if new CB versions use valid PFS format //NB: All CodeBreaker versions up to v9.3 use invalid formats if(!strncmp(hddEnt.name, "PP.",3)) { int len = strlen(hddEnt.name); if(!strcmp(hddEnt.name+len-4, ".PCB")) continue; } /* if(!strncmp(hddEnt.name, "__", 2)) { if(strcmp(hddEnt.name, "__boot")) continue; if(strcmp(hddEnt.name, "__net")) continue; if(strcmp(hddEnt.name, "__system")) continue; if(strcmp(hddEnt.name, "__sysconf")) continue; if(strcmp(hddEnt.name, "__common")) continue; } */ add_reg_entry(list->entries,hddEnt.name, n++); } fileXioDclose(hddFd); list->num = n; }
static err_t EnumDir(filestream* p,const tchar_t* Exts,bool_t ExtFilter,streamdir* Item) { iox_dirent_t Dirent; Item->FileName[0] = 0; Item->DisplayName[0] = 0; if (p->DevNo>=0) { static const tchar_t* const Devices[] = { "mass:", //"cdrom:", //driver doesn't support directory listing "hdd:", //"host:", //driver doesn't support directory listing "cdda:", "cdfs:", "smb:", NULL, }; for (;!Item->FileName[0];++p->DevNo) { int fd; const tchar_t* URL = Devices[p->DevNo]; if (!URL) break; fd = fileXioDopen(URL); if (fd>=0) { fileXioDclose(fd); tcscpy_s(Item->FileName,TSIZEOF(Item->FileName), URL); Item->ModifiedDate = INVALID_DATETIME_T; Item->Type = FTYPE_DIR; Item->Size = INVALID_FILEPOS_T; } } } else { if (p->FindDir<0) return ERR_END_OF_FILE; while (!Item->FileName[0]) { if (fileXioDread(p->FindDir,&Dirent)<=0) break; if (Dirent.name[0]=='.') // skip unix/mac hidden files continue; tcscpy_s(Item->FileName,TSIZEOF(Item->FileName), Dirent.name); Item->ModifiedDate = PS2ToDateTime(Dirent.stat.mtime); if (FIO_S_ISDIR(Dirent.stat.mode)) { Item->Type = FTYPE_DIR; Item->Size = INVALID_FILEPOS_T; } else { Item->Size = Dirent.stat.size; Item->Type = CheckExts(Item->FileName,Exts); if (!Item->Type && ExtFilter) Item->FileName[0] = 0; // skip } } } if (!Item->FileName[0]) { if (p->FindDir>=0) { fileXioDclose(p->FindDir); p->FindDir = -1; } return ERR_END_OF_FILE; } return ERR_NONE; }
int DirGetContents( const char *path, const char *filter, fileInfo_t *fileInfo, int maxItems ) { int c, i; char *ptr; int numRead; int index = 0; if( !path || !fileInfo || !maxItems ) return -1; if( (ptr = strchr( path, '/' )) == NULL ) { printf("DirGetContents : Invalid Path (ptr = NULL)\n"); return -1; } c = ptr - path; // try to read in dir from cd/dvd if( !strncmp( path, "cdfs:/", c ) ) { // just make sure we are initialized CD_Init(); struct TocEntry *tocEntries = (struct TocEntry*) malloc( sizeof(struct TocEntry) * maxItems ); if( !tocEntries ) return -1; CDVD_FlushCache(); numRead = CDVD_GetDir( ptr, NULL, CDVD_GET_FILES_AND_DIRS, tocEntries, maxItems, NULL ); CDVD_Stop(); index = 0; ptr = NULL; if( filter ) ptr = (char*) malloc( strlen(filter) + 1 ); for( i = 0; i < numRead; i++ ) { if( index >= maxItems ) break; if( !strcmp( tocEntries[i].filename, ".." ) || !strcmp( tocEntries[i].filename, "." ) ) continue; // check for filters c = 1; if( filter && !(tocEntries[i].fileProperties & FLAG_DIRECTORY) ) { strcpy( ptr, filter ); c = 0; char *token = strtok( ptr, " " ); while( token ) { // found matching extension if( CmpFileExtension( tocEntries[i].filename, token ) ) { c = 1; break; } token = strtok( NULL, " " ); } } if( c == 1 ) { strncpy( fileInfo[index].name, tocEntries[i].filename, sizeof(fileInfo[index].name) ); fileInfo[index].size = tocEntries[i].fileSize; fileInfo[index].flags = tocEntries[i].fileProperties; index++; } } if( ptr ) free(ptr); free(tocEntries); } else if( !strncmp( path, "pfs", 3 ) ) { // try to read in dir from hdd int hDir = fileXioDopen( path ); int nRet; iox_dirent_t dirEntry; if( hDir < 0 ) return -1; index = 0; ptr = NULL; if( filter ) ptr = (char*) malloc( strlen(filter) + 1 ); do { if( !(nRet = fileXioDread( hDir, &dirEntry )) ) break; if(!strcmp( dirEntry.name, "." ) || !strcmp( dirEntry.name, "..")) continue; if( index >= maxItems ) break; if( FIO_S_ISDIR(dirEntry.stat.mode) ) fileInfo[index].flags = FLAG_DIRECTORY; else fileInfo[index].flags = 0; // check for filters c = 1; if( filter && !(fileInfo[index].flags & FLAG_DIRECTORY) ) { strcpy( ptr, filter ); c = 0; char *token = strtok( ptr, " " ); while( token ) { // found matching extension if( CmpFileExtension( dirEntry.name, token ) ) { c = 1; break; } token = strtok( NULL, " " ); } } if( c == 1 ) { strncpy( fileInfo[index].name, dirEntry.name, sizeof(fileInfo[index].name) ); fileInfo[index].size = dirEntry.stat.size; index++; } } while( nRet > 0 ); if( ptr ) free(ptr); fileXioDclose( hDir ); } else if( !strncmp( path, "mc0:/", c ) || !strncmp( path, "mc1:/", c ) ) { // try to read in dir from memory card int nPort; char mcPath[256]; mcTable mcEntries[MAX_DIR_FILES] __attribute__((aligned(64))); if( !strncmp( path, "mc0:/", c ) ) nPort = 0; else nPort = 1; strcpy( mcPath, ptr ); strcat( mcPath, "*" ); mcGetDir( nPort, 0, mcPath, 0, MAX_DIR_FILES, mcEntries ); mcSync( 0, NULL, &numRead ); index = 0; ptr = NULL; if( filter ) ptr = (char*) malloc( strlen(filter) + 1 ); for( i = 0; i < numRead; i++ ) { if( index >= maxItems ) break; if( !strcmp( mcEntries[i].name, "." ) || !strcmp( mcEntries[i].name, "..") ) continue; if( mcEntries[i].attrFile & MC_ATTR_SUBDIR ) fileInfo[index].flags = FLAG_DIRECTORY; else fileInfo[index].flags = 0; // check for filters c = 1; if( filter && !(mcEntries[i].attrFile & MC_ATTR_SUBDIR) ) { strcpy( ptr, filter ); c = 0; char *token = strtok( ptr, " " ); while( token ) { // found matching extension if( CmpFileExtension( mcEntries[i].name, token ) ) { c = 1; break; } token = strtok( NULL, " " ); } } if( c == 1 ) { strncpy( fileInfo[index].name, mcEntries[i].name, sizeof(fileInfo[index].name) ); fileInfo[index].size = mcEntries[i].fileSizeByte; index++; } } if( ptr ) free(ptr); } else if( !strncmp( path, "mass:/", c ) ) { // try to read in dir from USB device int nRet; fat_dir_record dirEntry; // returns number of entries in directory nRet = usb_mass_getFirstDirentry( ptr, &dirEntry ); index = 0; ptr = NULL; if( filter ) ptr = (char*) malloc( strlen(filter) + 1 ); // loop through all entries in directory while( nRet > 0 ) { if(!strcmp( dirEntry.name, "." ) || !strcmp( dirEntry.name, "..")) { nRet = usb_mass_getNextDirentry(&dirEntry); continue; } // ignore volume label if( dirEntry.attr & USB_VOLUME ) { nRet = usb_mass_getNextDirentry(&dirEntry); continue; } if( index >= maxItems ) break; if( dirEntry.attr & USB_DIRECTORY ) fileInfo[index].flags = FLAG_DIRECTORY; else fileInfo[index].flags = 0; // check for filters c = 1; if( filter && !(fileInfo[index].flags & FLAG_DIRECTORY) ) { strcpy( ptr, filter ); c = 0; char *token = strtok( ptr, " " ); while( token ) { // found matching extension if( CmpFileExtension( dirEntry.name, token ) ) { c = 1; break; } token = strtok( NULL, " " ); } } if( c == 1 ) { strncpy( fileInfo[index].name, dirEntry.name, sizeof(fileInfo[index].name) ); fileInfo[index].size = dirEntry.size; index++; } nRet = usb_mass_getNextDirentry( &dirEntry ); } if( ptr ) free(ptr); } else if( !strncmp( path, "smb", 3 ) ) { // read from a samba share int hDir = smbc_opendir( path ); const struct smbc_dirent *dirEntry; if( hDir < 0 ) return -1; index = 0; ptr = NULL; if( filter ) ptr = (char*) malloc( strlen(filter) + 1 ); while( (dirEntry = smbc_readdir( hDir )) != NULL ) { if(!strcmp( dirEntry->name, "." ) || !strcmp( dirEntry->name, "..")) continue; if( index >= maxItems ) break; if( dirEntry->smbc_type == SMBC_DIR ) fileInfo[index].flags = FLAG_DIRECTORY; else fileInfo[index].flags = 0; // check for filters c = 1; if( filter && !(fileInfo[index].flags & FLAG_DIRECTORY) ) { strcpy( ptr, filter ); c = 0; char *token = strtok( ptr, " " ); while( token ) { // found matching extension if( CmpFileExtension( dirEntry->name, token ) ) { c = 1; break; } token = strtok( NULL, " " ); } } if( c == 1 ) { strncpy( fileInfo[index].name, dirEntry->name, sizeof(fileInfo[index].name) ); fileInfo[index].size = 0; // fixme index++; } }; if( ptr ) free(ptr); smbc_closedir( hDir ); } return index; }
int hddGetFilesystemList(t_hddFilesystem hddFs[], int maxEntries) { iox_dirent_t dirEnt; int count = 0; u32 size = 0; int hddFd; int rv; if(!hddStatusCurrent) hddUpdateInfo(); hddFd = fileXioDopen("hdd0:"); if(hddFd < 0) return hddFd; rv = fileXioDread(hddFd, &dirEnt); while((rv > 0) && (count < maxEntries)) { int i; int partitionFd; u32 zoneFree, zoneSize; // We only want to know about main partitions (non-empty ones at that :P) if((dirEnt.stat.attr & ATTR_SUB_PARTITION) || (dirEnt.stat.mode == FS_TYPE_EMPTY)) { rv = fileXioDread(hddFd, &dirEnt); continue; } memset(&hddFs[count], 0, sizeof(t_hddFilesystem)); sprintf(hddFs[count].filename, "hdd0:%s", dirEnt.name); // Work out filesystem type if((dirEnt.name[0] == '_') && (dirEnt.name[1] == '_')) { hddFs[count].fileSystemGroup = FS_GROUP_SYSTEM; strcpy(hddFs[count].name, &dirEnt.name[2]); } else if(dirEnt.name[0] == FS_COMMON_PREFIX) { hddFs[count].fileSystemGroup = FS_GROUP_COMMON; strcpy(hddFs[count].name, &dirEnt.name[1]); } else { hddFs[count].fileSystemGroup = FS_GROUP_APPLICATION; strcpy(hddFs[count].name, dirEnt.name); } #ifdef _OMIT_SYSTEM_PARTITION if((hddFs[count].fileSystemGroup == FS_GROUP_SYSTEM) && strcmp(hddFs[count].name, "boot")) { rv = fileXioDread(hddFd, &dirEnt); continue; } #endif #ifdef DEBUG printf("> Filename: %s\n> Name: %s\n> Type: %d\n", hddFs[count].filename, hddFs[count].name, hddFs[count].fileSystemGroup); #endif // Calculate filesystem size partitionFd = fileXioOpen(hddFs[count].filename, O_RDONLY, 0); // If we failed to open the partition, then a password is probably set // (usually this means we have tried to access a game partition). We // dont want to return un-accessible game partitions in the filesystem list.. if(partitionFd < 0) { rv = fileXioDread(hddFd, &dirEnt); continue; } for(i = 0, size = 0; i < dirEnt.stat.private_0 + 1; i++) { rv = fileXioIoctl2(partitionFd, HDDIO_GETSIZE, &i, 4, NULL, 0); size += rv * 512 / 1024 / 1024; } fileXioClose(partitionFd); hddFs[count].size = size; // Get filesystem free space & format status hddFs[count].freeSpace = 0; hddFs[count].formatted = 0; if(dirEnt.stat.mode == FS_TYPE_PFS) { rv = fileXioMount("pfs0:", hddFs[count].filename, FIO_MT_RDONLY); if(rv == 0) { zoneFree = fileXioDevctl("pfs0:", PFSCTL_GET_ZONE_FREE, NULL, 0, NULL, 0); zoneSize = fileXioDevctl("pfs0:", PFSCTL_GET_ZONE_SIZE, NULL, 0, NULL, 0); hddFs[count].freeSpace = zoneFree * zoneSize / 1024 / 1024; hddFs[count].formatted = 1; fileXioUmount("pfs0:"); } } #ifdef DEBUG printf("> Formatted: %d\n> Size: %d\n> Free: %d\n", hddFs[count].formatted, (int)hddFs[count].size, (int)hddFs[count].freeSpace); #endif count++; rv = fileXioDread(hddFd, &dirEnt); } rv = fileXioDclose(hddFd); return count; }
/**************************************************************************** * This function will read the contents of a directory and store the * * contents in the folder structure. The ext parameter works as a filter * * to read in only certain file extension types. After reading the * * directory, the function will sort the contents. * ****************************************************************************/ int readDirectory(char *ext, int media) { int ret = 1; iox_dirent_t directory; int size; char folderName[255]; unsigned int numToc, index; char *extcmp; folder.fIndex = 0; struct TocEntry cdDirectory[255]; size = strlen(ext); switch (media) { case 0: { while (ret > 0) { ret = fileXioDread(folder.iDir, &directory); if (ret > 0) { if (FIO_S_ISDIR(directory.stat.mode)) //is a directory { strcpy(folder.object[folder.fIndex].name, ""); strcat(folder.object[folder.fIndex].name, "/"); strcat(folder.object[folder.fIndex].name, directory.name); folder.object[folder.fIndex].type = 0; folder.object[folder.fIndex].count = folder.fIndex; folder.fIndex++; } else if (FIO_S_ISREG(directory.stat.mode)) //is a file { if (size > ret) size = 0; extcmp = &directory.name[ret-size]; if (strcasecmp(extcmp, ext) == 0) { strcpy(folder.object[folder.fIndex].name, directory.name); folder.object[folder.fIndex].type = 1; folder.object[folder.fIndex].count = folder.fIndex; folder.fIndex++; } } } } folder.fMax = folder.fIndex; folder.fIndex = 0; sortFolder(); for (ret = 0; ret < folder.fMax; ret++) { if (folder.object[ret].type == 0) { strcpy(folderName, &folder.object[ret].name[1]); strcpy(folder.object[ret].name, folderName); } } closeDirectory(MODE_HDD); return folder.fMax; } case 1: { numToc = CDVD_GetDir(&folder.directory[5], NULL, CDVD_GET_FILES_AND_DIRS, cdDirectory, 254, NULL); CDVD_Stop(); #define CD_S_ISDIR(x) x & 2 #define CD_S_ISFILE(x) !CD_S_ISDIR(x) for (index=0; index<numToc; index++) { if (CD_S_ISDIR(cdDirectory[index].fileProperties)) //is a folder { strcpy(folder.object[folder.fIndex].name, ""); strcat(folder.object[folder.fIndex].name, "/"); strcat(folder.object[folder.fIndex].name, cdDirectory[index].filename); folder.object[folder.fIndex].type = 0; folder.object[folder.fIndex].count = folder.fIndex; folder.fIndex++; } else { ret = strlen(cdDirectory[index].filename); if (size > ret) size = 0; extcmp = &cdDirectory[index].filename[ret-size]; if (strcasecmp(extcmp, ext) == 0) { strcpy(folder.object[folder.fIndex].name, cdDirectory[index].filename); folder.object[folder.fIndex].type = 1; folder.object[folder.fIndex].count = folder.fIndex; folder.fIndex++; } } } folder.fMax = folder.fIndex; folder.fIndex = 0; sortFolder(); for (ret = 0; ret < folder.fMax; ret++) { if (folder.object[ret].type == 0) { strcpy(folderName, &folder.object[ret].name[1]); strcpy(folder.object[ret].name, folderName); } } return folder.fMax; } } return 0; }