static err_t OpenDir(filestream* p,const tchar_t* URL,int UNUSED_PARAM(Flags)) { if (p->FindDir>=0) { fileXioDclose(p->FindDir); p->FindDir=-1; } if (!URL[0]) { p->DevNo = 0; return ERR_NONE; } p->DevNo = -1; p->FindDir = fileXioDopen(URL); if (p->FindDir<0) { int fd = fileXioOpen(URL,O_RDONLY,0); if (fd >= 0) { fileXioClose(fd); return ERR_NOT_DIRECTORY; } else return ERR_FILE_NOT_FOUND; } tcscpy_s(p->DirPath,TSIZEOF(p->DirPath),URL); AddPathDelimiter(p->DirPath,TSIZEOF(p->DirPath)); return ERR_NONE; }
int FileClose( FHANDLE handle ) { int ret = 0; if( handle.dt == DT_CD ) { ret = fioClose( handle.fh ); } else if( handle.dt == DT_HDD ) { ret = fileXioClose( handle.fh ); } else if( handle.dt == DT_MC ) { ret = fioClose( handle.fh ); } else if( handle.dt == DT_USB ) { ret = fioClose( handle.fh ); } else if( handle.dt == DT_HOST ) { ret = fioClose( handle.fh ); } else if( handle.dt == DT_SMB_SHARE ) { ret = smbc_close( handle.fh ); } return ret; }
void AsyncFio::close(int handle) { WaitSema(_ioSema); checkSync(); fileXioClose(handle); int res; fileXioWaitAsync(FXIO_WAIT, &res); if (res != 0) sioprintf("ERROR: fileXioClose failed, EC %d", res); _ioSlots[handle] = 0; SignalSema(_ioSema); }
bool_t FileExists(nodecontext *p,const tchar_t* Path) { // not all file systems supports fileXioGetstat tchar_t Tmp[MAXPATH]; int fd = fileXioOpen(CdromPath(Path,Tmp,TSIZEOF(Tmp)),O_RDONLY,0); if (fd >= 0) { fileXioClose(fd); return 1; } return 0; }
/**************************************************************************** * Universal file closing function. * ****************************************************************************/ void CloseFile(int handle, int media) { switch (media) { case 0: //hdd { fileXioClose(handle); break; } case 1: //cdfs { fioClose(handle); CDVD_Stop(); break; } case 2: //mc0 { //fioClose(handle); fileXioClose(handle); break; } case 3: { //fioClose(handle); fileXioClose(handle); break; } case 4: { fioClose(handle); break; } case 5: { fileXioClose(handle); break; } } }
static void Delete(filestream* p) { if (p->fd>=0) { fileXioClose(p->fd); p->fd = -1; } if (p->FindDir>=0) { fileXioDclose(p->FindDir); p->FindDir = -1; } }
static void appLaunchItem(int id, config_set_t* configSet) { struct config_value_t* cur = appGetConfigValue(id); int fd = fileXioOpen(cur->val, O_RDONLY, 0666); if (fd >= 0) { fileXioClose(fd); int exception = NO_EXCEPTION; if (strncmp(cur->val, "pfs0:", 5) == 0) exception = UNMOUNT_EXCEPTION; char filename[256]; sprintf(filename,"%s",cur->val); deinit(exception); // CAREFUL: deinit will call appCleanUp, so configApps/cur will be freed sysExecElf(filename); } else guiMsgBox(_l(_STR_ERR_FILE_INVALID), 0, NULL); }
static err_t Open(filestream* p, const tchar_t* URL, int Flags) { if (p->fd>=0) fileXioClose(p->fd); p->Length = INVALID_FILEPOS_T; p->fd = -1; if (URL && URL[0]) { tchar_t Tmp[MAXPATH]; int size; int mode = 0; URL = CdromPath(URL,Tmp,TSIZEOF(Tmp)); if (Flags & SFLAG_WRONLY && !(Flags & SFLAG_RDONLY)) mode = O_WRONLY; else if (Flags & SFLAG_RDONLY && !(Flags & SFLAG_WRONLY)) mode = O_RDONLY; else mode = O_RDWR; if (Flags & SFLAG_CREATE) mode |= O_CREAT|O_TRUNC; p->fd = fileXioOpen(URL, mode, FIO_S_IRUSR | FIO_S_IWUSR | FIO_S_IXUSR | FIO_S_IRGRP | FIO_S_IWGRP | FIO_S_IXGRP | FIO_S_IROTH | FIO_S_IWOTH | FIO_S_IXOTH ); if (p->fd<0) { if ((Flags & (SFLAG_REOPEN|SFLAG_SILENT))==0) NodeReportError(p,NULL,ERR_ID,ERR_FILE_NOT_FOUND,URL); return ERR_FILE_NOT_FOUND; } tcscpy_s(p->URL,TSIZEOF(p->URL),URL); if ((size = fileXioLseek(p->fd, 0, SEEK_END)) >= 0) { fileXioLseek(p->fd, 0, SEEK_SET); p->Length = size; } } return ERR_NONE; }
void Ps2FilesystemNode::doverify(void) { PS2Device medium; int fd; if (_verified) return; _verified = true; dbg_printf(" verify: %s -> ", _path.c_str()); #if 0 if (_path.empty()) { dbg_printf("PlayStation 2 Root !\n"); _verified = true; return; } if (_path.lastChar() == ':') { dbg_printf("Dev: %s\n", _path.c_str()); _verified = true; return; } #endif if (_path[3] != ':' && _path[4] != ':') { dbg_printf("relative path !\n"); _isHere = false; _isDirectory = false; return; } medium = _getDev(_path); if (medium == ERR_DEV) { _isHere = false; _isDirectory = false; return; } switch (medium) { #if 0 case HD_DEV: /*stat*/ case USB_DEV: iox_stat_t stat; fileXioGetStat(_path.c_str(), &stat); fileXioWaitAsync(FXIO_WAIT, &fd); if (!fd) { dbg_printf(" yes [stat]\n"); return true; } break; #endif case CD_DEV: /*no stat*/ case HD_DEV: case USB_DEV: case HOST_DEV: case MC_DEV: #if 1 fd = fio.open(_path.c_str(), O_RDONLY); dbg_printf("_path = %s -- fio.open -> %d\n", _path.c_str(), fd); if (fd >=0) { fio.close(fd); dbg_printf(" yes [open]\n"); _isHere = true; if (medium==MC_DEV && _path.lastChar()=='/') _isDirectory = true; else _isDirectory = false; return; } fd = fio.dopen(_path.c_str()); if (fd >=0) { fio.dclose(fd); dbg_printf(" yes [dopen]\n"); _isHere = true; _isDirectory = true; return; } #else fileXioOpen(_path.c_str(), O_RDONLY, DEFAULT_MODE); fileXioWaitAsync(FXIO_WAIT, &fd); if (fd>=0) { fileXioClose(fd); fileXioWaitAsync(FXIO_WAIT, &fd); return true; } fileXioDopen(_path.c_str()); fileXioWaitAsync(FXIO_WAIT, &fd); if (fd>=0) { fileXioDclose(fd); fileXioWaitAsync(FXIO_WAIT, &fd); return true; } #endif break; case ERR_DEV: _isHere = false; _isDirectory = false; break; } _isHere = false; _isDirectory = false; dbg_printf(" no\n"); return; }
/**************************************************************************** * Helper function. Not used anymore. * ****************************************************************************/ void closeShop(int handle) { fileXioClose(handle); fileXioUmount("pfs0:"); }
static void ethLaunchGame(int id, config_set_t* configSet) { int i, compatmask; int EnablePS2Logo = 0; #ifdef CHEAT int result; #endif char filename[32], partname[256]; base_game_info_t* game = ðGames[id]; struct cdvdman_settings_smb *settings; u32 layer1_start, layer1_offset; unsigned short int layer1_part; if (!gPCShareName[0]) { memcpy(gPCShareName, game->name, 32); ethULSizePrev = -2; ethGameCount = 0; ioPutRequest(IO_MENU_UPDATE_DEFFERED, ðGameList.mode); // clear the share list ioPutRequest(IO_CUSTOM_SIMPLEACTION, ðInitSMB); ioPutRequest(IO_MENU_UPDATE_DEFFERED, ðGameList.mode); // reload the game list return; } #ifdef VMC char vmc_name[32]; int vmc_id, size_mcemu_irx = 0; smb_vmc_infos_t smb_vmc_infos; vmc_superblock_t vmc_superblock; for (vmc_id = 0; vmc_id < 2; vmc_id++) { memset(&smb_vmc_infos, 0, sizeof(smb_vmc_infos_t)); configGetVMC(configSet, vmc_name, sizeof(vmc_name), vmc_id); if (vmc_name[0]) { if (sysCheckVMC(ethPrefix, "\\", vmc_name, 0, &vmc_superblock) > 0) { smb_vmc_infos.flags = vmc_superblock.mc_flag & 0xFF; smb_vmc_infos.flags |= 0x100; smb_vmc_infos.specs.page_size = vmc_superblock.page_size; smb_vmc_infos.specs.block_size = vmc_superblock.pages_per_block; smb_vmc_infos.specs.card_size = vmc_superblock.pages_per_cluster * vmc_superblock.clusters_per_card; smb_vmc_infos.active = 1; smb_vmc_infos.fid = 0xFFFF; if (gETHPrefix[0]) snprintf(smb_vmc_infos.fname, sizeof(smb_vmc_infos.fname), "%s\\VMC\\%s.bin", gETHPrefix, vmc_name); else snprintf(smb_vmc_infos.fname, sizeof(smb_vmc_infos.fname), "VMC\\%s.bin", vmc_name); } else { char error[256]; snprintf(error, sizeof(error), _l(_STR_ERR_VMC_CONTINUE), vmc_name, (vmc_id + 1)); if (!guiMsgBox(error, 1, NULL)) return; } } for (i = 0; i < size_smb_mcemu_irx; i++) { if (((u32*)&smb_mcemu_irx)[i] == (0xC0DEFAC0 + vmc_id)) { if (smb_vmc_infos.active) size_mcemu_irx = size_smb_mcemu_irx; memcpy(&((u32*)&smb_mcemu_irx)[i], &smb_vmc_infos, sizeof(smb_vmc_infos_t)); break; } } } #endif #ifdef CHEAT if((result = sbLoadCheats(ethPrefix, game->startup)) < 0) { switch(result) { case -ENOENT: guiWarning(_l(_STR_NO_CHEATS_FOUND), 10); break; default: guiWarning(_l(_STR_ERR_CHEATS_LOAD_FAILED), 10); } } #endif if (gRememberLastPlayed) { configSetStr(configGetByType(CONFIG_LAST), "last_played", game->startup); saveConfig(CONFIG_LAST, 0); } compatmask = sbPrepare(game, configSet, size_smb_cdvdman_irx, &smb_cdvdman_irx, &i); settings = (struct cdvdman_settings_smb *)((u8*)(&smb_cdvdman_irx)+i); switch(game->format) { case GAME_FORMAT_OLD_ISO: sprintf(settings->filename, "%s.%s%s", game->startup, game->name, game->extension); break; case GAME_FORMAT_ISO: sprintf(settings->filename, "%s%s", game->name, game->extension); break; default: //USBExtreme format. sprintf(settings->filename, "ul.%08X.%s", USBA_crc32(game->name), game->startup); settings->common.flags |= IOPCORE_SMB_FORMAT_USBLD; } sprintf(settings->smb_ip, "%u.%u.%u.%u", pc_ip[0], pc_ip[1], pc_ip[2], pc_ip[3]); settings->smb_port=gPCPort; strcpy(settings->smb_share, gPCShareName); strcpy(settings->smb_prefix, gETHPrefix); strcpy(settings->smb_user, gPCUserName); strcpy(settings->smb_password, gPCPassword); //Initialize layer 1 information. switch(game->format) { case GAME_FORMAT_USBLD: sprintf(partname, "%s%s.00", ethPrefix, settings->filename); break; default: //Raw ISO9660 disc image; one part. sprintf(partname, "%s%s\\%s", ethPrefix, game->media == 0x12?"CD":"DVD", settings->filename); } if (gPS2Logo) { int fd = fileXioOpen(partname, O_RDONLY, 0666); if (fd >= 0) { EnablePS2Logo = CheckPS2Logo(fd, 0); fileXioClose(fd); } } layer1_start = sbGetISO9660MaxLBA(partname); switch(game->format) { case GAME_FORMAT_USBLD: layer1_part = layer1_start / 0x80000; layer1_offset = layer1_start % 0x80000; sprintf(partname, "%s%s.%02x", ethPrefix, settings->filename, layer1_part); break; default: //Raw ISO9660 disc image; one part. layer1_part = 0; layer1_offset = layer1_start; } if(sbProbeISO9660_64(partname, game, layer1_offset) != 0) { layer1_start = 0; LOG("DVD detected.\n"); } else { layer1_start -= 16; LOG("DVD-DL layer 1 @ part %u sector 0x%lx.\n", layer1_part, layer1_offset); } settings->common.layer1_start = layer1_start; // disconnect from the active SMB session ethSMBDisconnect(); if (configGetStrCopy(configSet, CONFIG_ITEM_ALTSTARTUP, filename, sizeof(filename)) == 0) strcpy(filename, game->startup); deinit(NO_EXCEPTION); // CAREFUL: deinit will call ethCleanUp, so ethGames/game will be freed #ifdef VMC #define ETH_MCEMU size_mcemu_irx,&smb_mcemu_irx, #else #define ETH_MCEMU #endif sysLaunchLoaderElf(filename, "ETH_MODE", size_smb_cdvdman_irx, &smb_cdvdman_irx, ETH_MCEMU EnablePS2Logo, compatmask); }
static int ethPrepareMcemu(base_game_info_t* game) { char vmc[2][32]; char vmc_path[255]; u32 vmc_size; int i, j, fd, size_mcemu_irx = 0; smb_vmc_infos_t smb_vmc_infos; vmc_superblock_t vmc_superblock; configGetVMC(game->startup, vmc[0], ETH_MODE, 0); configGetVMC(game->startup, vmc[1], ETH_MODE, 1); for(i=0; i<2; i++) { if(!vmc[i][0]) // skip if empty continue; memset(&smb_vmc_infos, 0, sizeof(smb_vmc_infos_t)); memset(&vmc_superblock, 0, sizeof(vmc_superblock_t)); snprintf(vmc_path, 255, "%s\\VMC\\%s.bin", ethPrefix, vmc[i]); fd = fileXioOpen(vmc_path, O_RDONLY, 0666); if (fd >= 0) { size_mcemu_irx = -1; LOG("%s open\n", vmc_path); vmc_size = fileXioLseek(fd, 0, SEEK_END); fileXioLseek(fd, 0, SEEK_SET); fileXioRead(fd, (void*)&vmc_superblock, sizeof(vmc_superblock_t)); LOG("File size : 0x%X\n", vmc_size); LOG("Magic : %s\n", vmc_superblock.magic); LOG("Card type : %d\n", vmc_superblock.mc_type); if(!strncmp(vmc_superblock.magic, "Sony PS2 Memory Card Format", 27) && vmc_superblock.mc_type == 0x2) { smb_vmc_infos.flags = vmc_superblock.mc_flag & 0xFF; smb_vmc_infos.flags |= 0x100; smb_vmc_infos.specs.page_size = vmc_superblock.page_size; smb_vmc_infos.specs.block_size = vmc_superblock.pages_per_block; smb_vmc_infos.specs.card_size = vmc_superblock.pages_per_cluster * vmc_superblock.clusters_per_card; LOG("flags : 0x%X\n", smb_vmc_infos.flags ); LOG("specs.page_size : 0x%X\n", smb_vmc_infos.specs.page_size ); LOG("specs.block_size : 0x%X\n", smb_vmc_infos.specs.block_size); LOG("specs.card_size : 0x%X\n", smb_vmc_infos.specs.card_size ); if(vmc_size == smb_vmc_infos.specs.card_size * smb_vmc_infos.specs.page_size) { smb_vmc_infos.active = 1; smb_vmc_infos.fid = 0xFFFF; snprintf(vmc_path, 255, "VMC\\%s.bin", vmc[i]); strncpy(smb_vmc_infos.fname, vmc_path, 32); // maybe a too small size here ... LOG("%s is a valid Vmc file\n", smb_vmc_infos.fname ); } } fileXioClose(fd); } for (j=0; j<size_smb_mcemu_irx; j++) { if (((u32*)&smb_mcemu_irx)[j] == (0xC0DEFAC0 + i)) { if(smb_vmc_infos.active) size_mcemu_irx = size_smb_mcemu_irx; memcpy(&((u32*)&smb_mcemu_irx)[j], &smb_vmc_infos, sizeof(smb_vmc_infos_t)); break; } } } return size_mcemu_irx; }
int hddExpandFilesystem(t_hddFilesystem *fs, int extraMB) { int maxIndex; int useIndex; int partSize; int fsSizeLeft = extraMB; int partFd; int retVal; if(!hddStatusCurrent) hddUpdateInfo(); if(extraMB % 128) return -EINVAL; // Get index for max partition size for(maxIndex = 0; maxIndex < 9; maxIndex++) if(sizesMB[maxIndex] == hddMaxPartitionSize) break; // Get index of size we will use to create new subs for(useIndex = maxIndex; sizesMB[useIndex] > extraMB; useIndex--); partSize = sizesMB[useIndex]; // Open partition partFd = fileXioOpen(fs->filename, O_RDWR, 0); if(partFd < 0) return partFd; while(fsSizeLeft) { // Adjust size if necessary if(fsSizeLeft < partSize) { #ifdef DEBUG printf(">>> Adjusting sub size: %d MB to ", sizesMB[useIndex]); #endif for(useIndex = maxIndex; sizesMB[useIndex] > fsSizeLeft; useIndex--); partSize = sizesMB[useIndex]; maxIndex = useIndex; #ifdef DEBUG printf("%d MB\n", sizesMB[useIndex]); #endif } // Try and allocate new sub #ifdef DEBUG printf(">>> Attempting to create sub partition of size %d MB\n", sizesMB[useIndex]); #endif retVal = fileXioIoctl2(partFd, HDDIO_ADD_SUB, sizesString[useIndex], strlen(sizesString[useIndex]) + 1, NULL, 0); if(retVal == -ENOSPC) { // If sub alloc fails due to size, we decrease size and try again. // If we've run out of sizes, break the loop (give up) useIndex--; partSize = sizesMB[useIndex]; maxIndex = useIndex; if(useIndex < 0) { #ifdef DEBUG printf(">>> Out of sizes to try. Giving up.\n"); #endif break; } #ifdef DEBUG printf(">>> Subpartition alloc FAILED! Trying with size of %d MB\n", partSize); #endif continue; } // If we've reached the max number of subs, bail. else if(retVal == -EFBIG) break; else if(retVal >= 0) { #ifdef DEBUG printf(">>> Sub creation successfull!\n"); #endif } else { #ifdef DEBUG printf(">>> Unknown error while creating sub: %d\n", retVal); #endif } fsSizeLeft -= sizesMB[useIndex]; } fileXioClose(partFd); hddUpdateInfo(); return extraMB - fsSizeLeft; }
int hddMakeFilesystem(int fsSizeMB, char *name, int type) { int formatArg[3] = { PFS_ZONE_SIZE, 0x2d66, PFS_FRAGMENT }; int maxIndex; int useIndex; int partSize; int fsSizeLeft = fsSizeMB; int partFd; char openString[256]; char fsName[256]; int retVal; if(!hddStatusCurrent) hddUpdateInfo(); if(fsSizeMB % 128) return -EINVAL; switch(type) { case FS_GROUP_SYSTEM: sprintf(fsName, "__%s", name); break; case FS_GROUP_COMMON: sprintf(fsName, "+%s", name); break; default: strcpy(fsName, name); break; } // Check if filesystem already exists sprintf(openString, "hdd0:%s", fsName); partFd = fileXioOpen(openString, O_RDONLY, 0); if(partFd > 0) // Filesystem already exists { fileXioClose(partFd); return -1; } // Get index for max partition size for(maxIndex = 0; maxIndex < 9; maxIndex++) if(sizesMB[maxIndex] == hddMaxPartitionSize) break; // Get index of size we will use to create main partition for(useIndex = maxIndex; sizesMB[useIndex] > fsSizeMB; useIndex--); partSize = sizesMB[useIndex]; #ifdef DEBUG printf(">>> Attempting to create main partition, size %d MB\n", partSize); #endif sprintf(openString, "hdd0:%s,%s", fsName, sizesString[useIndex]); #ifdef DEBUG printf(">>> openString = %s\n", openString); #endif partFd = fileXioOpen(openString, O_RDWR | O_CREAT, 0); if(partFd < 0) return partFd; fsSizeLeft -= partSize; #ifdef DEBUG printf(">>> Main partition of %d MB created!\n", partSize); #endif while(fsSizeLeft) { // Adjust size if necessary if(fsSizeLeft < partSize) { #ifdef DEBUG printf(">>> Adjusting sub size: %d MB to ", sizesMB[useIndex]); #endif for(useIndex = maxIndex; sizesMB[useIndex] > fsSizeLeft; useIndex--); partSize = sizesMB[useIndex]; maxIndex = useIndex; #ifdef DEBUG printf("%d MB\n", sizesMB[useIndex]); #endif } // Try and allocate sub #ifdef DEBUG printf(">>> Attempting to create sub partition of size %d MB\n", sizesMB[useIndex]); #endif retVal = fileXioIoctl2(partFd, HDDIO_ADD_SUB, sizesString[useIndex], strlen(sizesString[useIndex]) + 1, NULL, 0); if(retVal == -ENOSPC) { // If sub alloc fails due to size, we decrease size and try again. // If we've run out of sizes, break the loop (give up) useIndex--; partSize = sizesMB[useIndex]; maxIndex = useIndex; if(useIndex < 0) { #ifdef DEBUG printf(">>> Out of sizes to try. Giving up.\n"); #endif break; } #ifdef DEBUG printf(">>> Subpartition alloc FAILED! Trying with size of %d MB\n", partSize); #endif continue; } // If we've reached the max number of subs, bail. else if(retVal == -EFBIG) break; else if(retVal >= 0) { #ifdef DEBUG printf(">>> Sub creation successfull!\n"); #endif } else { #ifdef DEBUG printf(">>> Unknown error while creating sub: %d\n", retVal); #endif } fsSizeLeft -= sizesMB[useIndex]; } fileXioClose(partFd); sprintf(openString, "hdd0:%s", fsName); retVal = fileXioFormat("pfs:", openString, (const char*)&formatArg, sizeof(formatArg)); if(retVal < 0) { #ifdef DEBUG printf(">>> Failed to format new partition: %d\n", retVal); #endif return retVal; } hddUpdateInfo(); return fsSizeMB - fsSizeLeft; }
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; }