Пример #1
0
s32 handleFFSIoctlv(ipcmessage *msg)
{
	int ret; 
	ioctlv *vector = msg->ioctlv.vector;
	u32 num_io = msg->ioctlv.num_io;
	
	switch(msg->ioctlv.command) {
	case FFS_IOCTLV_READDIR: {
		if (emulationType == 0)
			goto handleOriginal;

		char newpath[MAX_FILENAME_SIZE];
		u32 len;

		char *dirpath = (char *)vector[0].data;
		u32 *outlen =  (u32 *)vector[1].data;
		void *outbuf;

		if (num_io > 1) {
			outbuf = (char *)vector[2].data;
			outlen =  (u32 *)vector[3].data;
		} else
			outbuf = NULL;

		preappend_nand_dev_name(dirpath, newpath);
		ret = FAT_ReadDir(newpath, outbuf, &len);
		if (ret >= 0) 
			*outlen = len;
		break;
	}
	case FFS_IOCTLV_0C:
		if (emulationType == 0)
			goto handleOriginal;
		u32 *ptr1 = (u32*) vector[1].data;
		u32 *ptr2 = (u32*) vector[2].data;
		*ptr1 = 1;
		*ptr2 = 1;
		os_sync_after_write(ptr1, 4);
		os_sync_after_write(ptr2, 4);
		ret = 0;
		break;
	handleOriginal:
	default:
		ret = handleFFSIoctlv(msg);
	}
	return ret;
}
Пример #2
0
s32 FS_Ioctlv(ipcmessage *message, u32 *flag)
{
    ioctlv *vector = message->ioctlv.vector;
    u32     inlen  = message->ioctlv.num_in;
    u32     iolen  = message->ioctlv.num_io;
    u32     cmd    = message->ioctlv.command;

    s32 ret;

    /* Set flag */
    *flag = config.mode;

    /* Parse comamnd */
    switch (cmd) {
    /** Read directory **/
    case IOCTL_ISFS_READDIR: {
        char *dirpath = (char *)vector[0].data;

        FS_printf("FS_Readdir(): %s\n", dirpath);

        /* Check path */
        ret = FS_CheckPath(dirpath);
        if (ret) {
            *flag = 0;
            break;
        }

        /* FAT mode */
        if (config.mode) {
            char *outbuf = NULL;
            u32  *outlen = NULL;
            u32   buflen = 0;

            char fatpath[FAT_MAXPATH];
            u32  entries;

            /* Set pointers/values */
            if (iolen > 1) {
                entries = *(u32 *)vector[1].data;
                outbuf  = (char *)vector[2].data;
                outlen  =  (u32 *)vector[3].data;
                buflen  =         vector[2].len;
            } else
                outlen  =  (u32 *)vector[1].data;

            /* Generate path */
            FS_GeneratePath(dirpath, fatpath);

            /* Read directory */
            ret = FAT_ReadDir(fatpath, outbuf, &entries);
            if (ret >= 0) {
                *outlen = entries;
                os_sync_after_write(outlen, sizeof(u32));
            }

            /* Flush cache */
            if (outbuf)
                os_sync_after_write(outbuf, buflen);

            return ret;
        }

        break;
    }

    /** Get device usage **/
    case IOCTL_ISFS_GETUSAGE: {
        char *dirpath = (char *)vector[0].data;

        FS_printf("FS_GetUsage(): %s\n", dirpath);

        /* Check path */
        ret = FS_CheckPath(dirpath);
        if (ret) {
            *flag = 0;
            break;
        }

        /* FAT mode */
        if (config.mode) {
            char fatpath[FAT_MAXPATH];

            u32 *blocks = (u32 *)vector[1].data;
            u32 *inodes = (u32 *)vector[2].data;

            /* Generate path */
            FS_GeneratePath(dirpath, fatpath);

            /* Get usage */
            ret = FAT_GetUsage(fatpath, blocks, inodes);

            /* Flush cache */
            os_sync_after_write(blocks, sizeof(u32));
            os_sync_after_write(inodes, sizeof(u32));

            return ret;
        }

        break;
    }

    /** Set FS mode **/
    case IOCTL_ISFS_SETMODE: {
        u32   val  = *(u32 *)vector[0].data;
        char *path = "";

        /* Get path */
        if (inlen > 1)
            path = (char *)vector[1].data;

        /* Set flag */
        *flag = 1;

        /* Set path */
        strcpy(config.path, path);

        /* FAT mode enabled */
        if (val) {
            char fatpath[FAT_MAXPATH];

            /* Initialize FAT */
            ret = FAT_Init();
            if (ret < 0)
                return ret;

            /* Generate path */
            FS_GeneratePath("/tmp", fatpath);

            /* Delete "/tmp" */
            FAT_DeleteDir(fatpath);
        }

        /* Set FS mode */
        config.mode = val;

        return 0;
    }

    default:
        break;
    }

    /* Call handler */
    return -6;
}
Пример #3
0
s32 __FAT_Ioctlv(s32 fd, u32 cmd, ioctlv *vector, u32 inlen, u32 iolen)
{
	s32 ret = IPC_EINVAL;

	/* Invalidate cache */
	InvalidateVector(vector, inlen, iolen);

	/* Parse command */
	switch (cmd) {
	/** Create directory **/
	case IOCTL_FAT_MKDIR: {
		char *dirpath = (char *)vector[0].data;

		dbg_printf("FAT: IOCTL_FAT_MKDIR: fd = %d, dirpath = %s\n", fd, dirpath);

		/* Sart blinking */
		Led_BlinkOn();

		/* Create directory */
		ret = FAT_CreateDir(dirpath);

		/* Stop blinking */
		Led_BlinkOff();

		dbg_printf("FAT: IOCTL_FAT_MKDIR: ret = %d\n", ret);

		break;
	}

	/** Create file **/
	case IOCTL_FAT_MKFILE: {
		char *filepath = (char *)vector[0].data;

		dbg_printf("FAT: IOCTL_FAT_MKFILE: fd = %d, filepath = %s\n", fd, filepath);

		/* Sart blinking */
		Led_BlinkOn();

		/* Create file */
		ret = FAT_CreateFile(filepath);

		/* Stop blinking */
		Led_BlinkOff();

		dbg_printf("FAT: IOCTL_FAT_MKFILE: ret = %d\n", ret);

		break;
	}

	/** Read directory **/
	case IOCTL_FAT_READDIR_FS:
	case IOCTL_FAT_READDIR: {
		char *dirpath = (char *)vector[0].data;
		char *outbuf  = NULL;
		u32  *outlen  = NULL;

		u32 buflen  = 0;
		u32 entries = 0, forFS;

		/* Set FS flag */
		forFS = (cmd == IOCTL_FAT_READDIR_FS);

		dbg_printf("FAT: IOCTL_FAT_READDIR%s: fd = %d, dirpath = %s\n", forFS? "_FS" : "", fd, dirpath);

		/* Input values */
		if (iolen > 1) {
			entries = *(u32 *)vector[1].data;
			outbuf  = (char *)vector[2].data;
			outlen  =  (u32 *)vector[3].data;
			buflen  =         vector[2].len;
		} else
			outlen =  (u32 *)vector[1].data;

		/* Read directory */
		ret = FAT_ReadDir(dirpath, outbuf, buflen, outlen, entries, forFS);

		dbg_printf("FAT: IOCTL_FAT_READDIR%s: ret = %d\n", forFS? "_FS" : "", ret);

		break;
	}

	/** Delete object **/
	case IOCTL_FAT_DELETE: {
		char *path = (char *)vector[0].data;

 		dbg_printf("FAT: IOCTL_FAT_DELETE: fd = %d, path = %s\n", fd, path);

		/* Sart blinking */
		Led_BlinkOn();

		/* Delete file/directory */
		ret = FAT_Delete(path);

		/* Stop blinking */
		Led_BlinkOff();

 		dbg_printf("FAT: IOCTL_FAT_DELETE: ret = %d\n", ret);

		break;
	}

	/** Delete directory **/
	case IOCTL_FAT_DELETEDIR: {
		char *dirpath = (char *)vector[0].data;
 		dbg_printf("FAT: IOCTL_FAT_DELETEDIR: fd = %d, path = %s\n", fd, dirpath);

		/* Sart blinking */
		Led_BlinkOn();

		/* Delete directory */
		ret = FAT_DeleteDir(dirpath);

		/* Stop blinking */
		Led_BlinkOff();

 		dbg_printf("FAT: IOCTL_FAT_DELETEDIR: ret = %d\n", ret);

		break;
	}

	/** Rename object **/
	case IOCTL_FAT_RENAME: {
		char *oldname = (char *)vector[0].data;
		char *newname = (char *)vector[1].data;
 		dbg_printf("FAT: IOCTL_FAT_RENAME: fd = %d, from = %s, to = %s\n", fd, oldname, newname);

		/* Sart blinking */
		Led_BlinkOn();

		/* Rename object */
		ret = FAT_Rename(oldname, newname);

		/* Stop blinking */
		Led_BlinkOff();

 		dbg_printf("FAT: IOCTL_FAT_RENAME: ret = %d\n", ret);

		break;
	}

	/** Get stats **/
	case IOCTL_FAT_STATS: {
		char *path  = (char *)vector[0].data;
		void *stats = (void *)vector[1].data;
 		dbg_printf("FAT: IOCTL_FAT_STATS: fd = %d, path = %s\n", fd, path);

		/* Get stats */
		ret = FAT_GetStats(path, stats);
 		dbg_printf("FAT: IOCTL_FAT_STATS: ret = %d, size = %d\n", ret, ((struct stats *)stats)->size);

		break;
	}

	/** Get usage **/
	case IOCTL_FAT_GETUSAGE_FS:
	case IOCTL_FAT_GETUSAGE: {
		char *path  = (char *)vector[0].data;
		u64  *size  =  (u64 *)vector[1].data;
		u32  *files =  (u32 *)vector[2].data;
		u32  *dirs  =  (u32 *)vector[3].data;
		u32  fakedirs, fakefiles, forFS;

		/* Set default pointers */
		if (iolen < 2)
			files = &fakefiles;
		if (iolen < 3)
			dirs = &fakedirs;

		/* Set initial values */
		*size  = 0;
		*files = 0;
		*dirs  = 0;
			
		/* Set FS flag */
		forFS = (cmd == IOCTL_FAT_GETUSAGE_FS);
 		dbg_printf("FAT: IOCTL_FAT_GETUSAGE%s: fd = %d, path = %s\n", forFS?"_FS":"", fd, path);

		/* Get usage */
		ret = FAT_GetUsage(path, size, files, dirs, forFS);
 		dbg_printf("FAT: IOCTL_FAT_GETUSAGE: ret = %d, size = %dl, files = %d, dirs = %d\n", ret, *size, *files, *dirs);

		break;
	}

	/** Mount SD card **/
	case IOCTL_FAT_MOUNT_SD: {
		s32 partition = inlen > 0 ? *(s32 *)vector[0].data : -1;

		/* Mount SD card */
		ret = FAT_Mount(0, partition);

		break;
	}

	/** Unmount SD card **/
	case IOCTL_FAT_UMOUNT_SD: {
		/* Unmount SD card */
		ret = FAT_Unmount(0);
		if (ret < 0)
			break;

		/* Deinitialize SDIO */
		ret = sdio_Shutdown();
		if (!ret)
			ret = IPC_EINVAL;

		break;
	}

	/** Mount USB device **/
	case IOCTL_FAT_MOUNT_USB: {
		s32 partition = inlen > 0 ? *(s32 *)vector[0].data : -1;

		/* Mount USB device */
		ret = FAT_Mount(1, partition);

		break;
	}

	/** Unmount USB card **/
	case IOCTL_FAT_UMOUNT_USB: {
		/* Unmount USB */
		ret = FAT_Unmount(1);
		if (ret < 0)
			break;

		/* Deinitialize USB */
		ret = usbstorage_Shutdown();
		if (!ret)
			ret = IPC_EINVAL;

		break;
	}

	/** Get mounted partition of the given device **/
	case IOCTL_FAT_GETPARTITION: {
		u32 device = *(u32 *)vector[0].data;
		u32 *partition = (u32 *)vector[1].data;

		/* Get partition */
		ret = FAT_GetPartition(device, partition);

		break;
	}

	default:
		break;
	}

	/* Flush cache */
	FlushVector(vector, inlen, iolen);

	return ret;
}
Пример #4
0
s32 FAT_Ioctlv(s32 fd, u32 cmd, ioctlv *vector, u32 inlen, u32 iolen)
{
	s32 ret = IPC_EINVAL;

	/* Invalidate ache */
	InvalidateVector(vector, inlen, iolen);

	/* Parse command */
	switch (cmd) {
	/** Create directory **/
	case IOCTL_FAT_MKDIR: {
		char *dirpath = (char *)vector[0].data;

		/* Create directory */
		ret = FAT_CreateDir(dirpath);

		break;
	}

	/** Create file **/
	case IOCTL_FAT_MKFILE: {
		char *filepath = (char *)vector[0].data;

		/* Create file */
		ret = FAT_CreateFile(filepath);

		break;
	}

	/** Read directory **/
	case IOCTL_FAT_READDIR: {
		char *dirpath = (char *)vector[0].data;
		char *outbuf  = NULL;
		u32  *outlen  = NULL;
		u32   buflen  = 0;

		u32 entries = 0;

		/* Input values */
		if (iolen > 1) {
			entries = *(u32 *)vector[1].data;
			outbuf  = (char *)vector[2].data;
			outlen  =  (u32 *)vector[3].data;
			buflen  =         vector[2].len;
		} else
			outlen  =  (u32 *)vector[1].data;

		/* Clear buffer */
		if (outbuf)
			memset(outbuf, 0, buflen);

		/* Read directory */
		ret = FAT_ReadDir(dirpath, outbuf, outlen, entries);

		break;
	}

	/** Read directory (LFN) **/
	case IOCTL_FAT_READDIR_LFN: {
		char *dirpath = (char *)vector[0].data;
		char *outbuf  = NULL;
		u32  *outlen  = NULL;
		u32   buflen  = 0;

		u32 entries = 0;

		/* Input values */
		if (iolen > 1) {
			entries = *(u32 *)vector[1].data;
			outbuf  = (char *)vector[2].data;
			outlen  =  (u32 *)vector[3].data;
			buflen  =         vector[2].len;
		} else
			outlen  =  (u32 *)vector[1].data;

		/* Clear buffer */
		if (outbuf)
			memset(outbuf, 0, buflen);

		/* Read directory (LFN) */
		ret = FAT_ReadDirLfn(dirpath, outbuf, outlen, entries);

		break;
	}

	/** Delete object **/
	case IOCTL_FAT_DELETE: {
		char *path = (char *)vector[0].data;

		/* Delete file/directory */
		ret = FAT_Delete(path);

		break;
	}

	/** Delete directory **/
	case IOCTL_FAT_DELETEDIR: {
		char *dirpath = (char *)vector[0].data;

		/* Delete directory */
		ret = FAT_DeleteDir(dirpath);

		break;
	}

	/** Rename object **/
	case IOCTL_FAT_RENAME: {
		char *oldname = (char *)vector[0].data;
		char *newname = (char *)vector[1].data;

		/* Rename file/directory */
		ret = FAT_Rename(oldname, newname);

		break;
	}

	/** Get stats **/
	case IOCTL_FAT_STAT: {
		char *path  = (char *)vector[0].data;
		void *stats = vector[1].data;

		/* Get stats */
		ret = FAT_Stat(path, stats);

		break;
	}

	/** Get filesystem stats **/
	case IOCTL_FAT_VFSSTATS: {
		char *path  = (char *)vector[0].data;
		void *stats = vector[1].data;

		/* Get filesystem stats */
		ret = FAT_GetVfsStats(path, stats);

		break;
	}

	/** Get usage **/
	case IOCTL_FAT_GETUSAGE: {
		char *path   = (char *)vector[0].data;
		u32  *blocks =  (u32 *)vector[1].data;
		u32  *inodes =  (u32 *)vector[2].data;

		u64 size;

		/* Reset values */
		*blocks = 0;
		*inodes = 0;

		/* Get usage */
		ret = FAT_GetUsage(path, &size, inodes);

		/* Not a directory */
		if (ret == -ENOTDIR) {
			ret = 0;
			break;
		}

		/* Calculate blocks */
		*blocks = (size / 0x4000);

		break;
	}


	/** Mount SD card **/
	case IOCTL_FAT_MOUNTSD: {
		/* Initialize SDIO */
		ret = !__io_wiisd.startup();
		if (ret)
			break;

		/* Mount SD card */
		ret = !fatMountSimple("sd", &__io_wiisd);

		break;
	}

	/** Unmount SD card **/
	case IOCTL_FAT_UMOUNTSD: {
		/* Unmount SD card */
		fatUnmount("sd");

		/* Deinitialize SDIO */
		ret = !__io_wiisd.shutdown();

		break;
	}

	/** Mount USB card **/
	case IOCTL_FAT_MOUNTUSB: {
		/* Initialize USB */
		ret = !__io_usbstorage.startup();
		if (ret)
			break;

		/* Mount USB */
		ret = !fatMountSimple("usb", &__io_usbstorage);

		break;
	}

	/** Unmount USB card **/
	case IOCTL_FAT_UMOUNTUSB: {
		/* Unmount USB */
		fatUnmount("usb");

		/* Deinitialize USB */
		ret = !__io_usbstorage.shutdown();

		break;
	}

	default:
		break;
	}

	/* Flush cache */
	FlushVector(vector, inlen, iolen);

	return ret;
}