📄 ioctl32.c
字号:
err = __put_user(pos.mt_blkno, &((struct mtpos32 *)arg)->mt_blkno); break; case MTIOCGET32: err = __put_user(get.mt_type, &((struct mtget32 *)arg)->mt_type); err |= __put_user(get.mt_resid, &((struct mtget32 *)arg)->mt_resid); err |= __put_user(get.mt_dsreg, &((struct mtget32 *)arg)->mt_dsreg); err |= __put_user(get.mt_gstat, &((struct mtget32 *)arg)->mt_gstat); err |= __put_user(get.mt_erreg, &((struct mtget32 *)arg)->mt_erreg); err |= __put_user(get.mt_fileno, &((struct mtget32 *)arg)->mt_fileno); err |= __put_user(get.mt_blkno, &((struct mtget32 *)arg)->mt_blkno); break; case MTIOCGETCONFIG32: err = __put_user(info.mt_type, &((struct mtconfiginfo32 *)arg)->mt_type); err |= __put_user(info.ifc_type, &((struct mtconfiginfo32 *)arg)->ifc_type); err |= __put_user(info.irqnr, &((struct mtconfiginfo32 *)arg)->irqnr); err |= __put_user(info.dmanr, &((struct mtconfiginfo32 *)arg)->dmanr); err |= __put_user(info.port, &((struct mtconfiginfo32 *)arg)->port); err |= __put_user(info.debug, &((struct mtconfiginfo32 *)arg)->debug); err |= __copy_to_user((char *)&((struct mtconfiginfo32 *)arg)->debug + sizeof(((struct mtconfiginfo32 *)arg)->debug), (char *)&info.debug + sizeof(info.debug), sizeof(__u32)); break; case MTIOCSETCONFIG32: break; } return err ? -EFAULT: 0;}struct cdrom_read32 { int cdread_lba; __kernel_caddr_t32 cdread_bufaddr; int cdread_buflen;};struct cdrom_read_audio32 { union cdrom_addr addr; u_char addr_format; int nframes; __kernel_caddr_t32 buf;};struct cdrom_generic_command32 { unsigned char cmd[CDROM_PACKET_SIZE]; __kernel_caddr_t32 buffer; unsigned int buflen; int stat; __kernel_caddr_t32 sense; __kernel_caddr_t32 reserved[3];};static int cdrom_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg){ mm_segment_t old_fs = get_fs(); struct cdrom_read cdread; struct cdrom_read_audio cdreadaudio; struct cdrom_generic_command cgc; __kernel_caddr_t32 addr; char *data = 0; void *karg; int err = 0; switch(cmd) { case CDROMREADMODE2: case CDROMREADMODE1: case CDROMREADRAW: case CDROMREADCOOKED: karg = &cdread; err = __get_user(cdread.cdread_lba, &((struct cdrom_read32 *)arg)->cdread_lba); err |= __get_user(addr, &((struct cdrom_read32 *)arg)->cdread_bufaddr); err |= __get_user(cdread.cdread_buflen, &((struct cdrom_read32 *)arg)->cdread_buflen); if (err) return -EFAULT; data = kmalloc(cdread.cdread_buflen, GFP_KERNEL); if (!data) return -ENOMEM; cdread.cdread_bufaddr = data; break; case CDROMREADAUDIO: karg = &cdreadaudio; err = copy_from_user(&cdreadaudio.addr, &((struct cdrom_read_audio32 *)arg)->addr, sizeof(cdreadaudio.addr)); err |= __get_user(cdreadaudio.addr_format, &((struct cdrom_read_audio32 *)arg)->addr_format); err |= __get_user(cdreadaudio.nframes, &((struct cdrom_read_audio32 *)arg)->nframes); err |= __get_user(addr, &((struct cdrom_read_audio32 *)arg)->buf); if (err) return -EFAULT; data = kmalloc(cdreadaudio.nframes * 2352, GFP_KERNEL); if (!data) return -ENOMEM; cdreadaudio.buf = data; break; case CDROM_SEND_PACKET: karg = &cgc; err = copy_from_user(cgc.cmd, &((struct cdrom_generic_command32 *)arg)->cmd, sizeof(cgc.cmd)); err |= __get_user(addr, &((struct cdrom_generic_command32 *)arg)->buffer); err |= __get_user(cgc.buflen, &((struct cdrom_generic_command32 *)arg)->buflen); if (err) return -EFAULT; if ((data = kmalloc(cgc.buflen, GFP_KERNEL)) == NULL) return -ENOMEM; cgc.buffer = data; break; default: do { static int count = 0; if (++count <= 20) printk("cdrom_ioctl: Unknown cmd fd(%d) " "cmd(%08x) arg(%08x)\n", (int)fd, (unsigned int)cmd, (unsigned int)arg); } while (0); return -EINVAL; } set_fs (KERNEL_DS); err = sys_ioctl (fd, cmd, (unsigned long)karg); set_fs (old_fs); if (err) goto out; switch (cmd) { case CDROMREADMODE2: case CDROMREADMODE1: case CDROMREADRAW: case CDROMREADCOOKED: err = copy_to_user((char *)A(addr), data, cdread.cdread_buflen); break; case CDROMREADAUDIO: err = copy_to_user((char *)A(addr), data, cdreadaudio.nframes * 2352); break; case CDROM_SEND_PACKET: err = copy_to_user((char *)A(addr), data, cgc.buflen); break; default: break; }out: if (data) kfree(data); return err ? -EFAULT : 0;}struct loop_info32 { int lo_number; /* ioctl r/o */ __kernel_dev_t32 lo_device; /* ioctl r/o */ unsigned int lo_inode; /* ioctl r/o */ __kernel_dev_t32 lo_rdevice; /* ioctl r/o */ int lo_offset; int lo_encrypt_type; int lo_encrypt_key_size; /* ioctl w/o */ int lo_flags; /* ioctl r/o */ char lo_name[LO_NAME_SIZE]; unsigned char lo_encrypt_key[LO_KEY_SIZE]; /* ioctl w/o */ unsigned int lo_init[2]; char reserved[4];};static int loop_status(unsigned int fd, unsigned int cmd, unsigned long arg){ mm_segment_t old_fs = get_fs(); struct loop_info l; int err = -EINVAL; switch(cmd) { case LOOP_SET_STATUS: err = get_user(l.lo_number, &((struct loop_info32 *)arg)->lo_number); err |= __get_user(l.lo_device, &((struct loop_info32 *)arg)->lo_device); err |= __get_user(l.lo_inode, &((struct loop_info32 *)arg)->lo_inode); err |= __get_user(l.lo_rdevice, &((struct loop_info32 *)arg)->lo_rdevice); err |= __copy_from_user((char *)&l.lo_offset, (char *)&((struct loop_info32 *)arg)->lo_offset, 8 + (unsigned long)l.lo_init - (unsigned long)&l.lo_offset); if (err) { err = -EFAULT; } else { set_fs (KERNEL_DS); err = sys_ioctl (fd, cmd, (unsigned long)&l); set_fs (old_fs); } break; case LOOP_GET_STATUS: set_fs (KERNEL_DS); err = sys_ioctl (fd, cmd, (unsigned long)&l); set_fs (old_fs); if (!err) { err = put_user(l.lo_number, &((struct loop_info32 *)arg)->lo_number); err |= __put_user(l.lo_device, &((struct loop_info32 *)arg)->lo_device); err |= __put_user(l.lo_inode, &((struct loop_info32 *)arg)->lo_inode); err |= __put_user(l.lo_rdevice, &((struct loop_info32 *)arg)->lo_rdevice); err |= __copy_to_user((char *)&((struct loop_info32 *)arg)->lo_offset, (char *)&l.lo_offset, (unsigned long)l.lo_init - (unsigned long)&l.lo_offset); if (err) err = -EFAULT; } break; default: { static int count = 0; if (++count <= 20) printk("%s: Unknown loop ioctl cmd, fd(%d) " "cmd(%08x) arg(%08lx)\n", __FUNCTION__, fd, cmd, arg); } } return err;}extern int tty_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg);#ifdef CONFIG_VTstatic int vt_check(struct file *file){ struct tty_struct *tty; struct inode *inode = file->f_dentry->d_inode; if (file->f_op->ioctl != tty_ioctl) return -EINVAL; tty = (struct tty_struct *)file->private_data; if (tty_paranoia_check(tty, inode->i_rdev, "tty_ioctl")) return -EINVAL; if (tty->driver.ioctl != vt_ioctl) return -EINVAL; /* * To have permissions to do most of the vt ioctls, we either have * to be the owner of the tty, or super-user. */ if (current->tty == tty || suser()) return 1; return 0; }struct consolefontdesc32 { unsigned short charcount; /* characters in font (256 or 512) */ unsigned short charheight; /* scan lines per character (1-32) */ u32 chardata; /* font data in expanded form */};static int do_fontx_ioctl(unsigned int fd, int cmd, struct consolefontdesc32 *user_cfd, struct file *file){ struct consolefontdesc cfdarg; struct console_font_op op; int i, perm; perm = vt_check(file); if (perm < 0) return perm; if (copy_from_user(&cfdarg, user_cfd, sizeof(struct consolefontdesc32))) return -EFAULT; cfdarg.chardata = (unsigned char *)A(((struct consolefontdesc32 *)&cfdarg)->chardata); switch (cmd) { case PIO_FONTX: if (!perm) return -EPERM; op.op = KD_FONT_OP_SET; op.flags = 0; op.width = 8; op.height = cfdarg.charheight; op.charcount = cfdarg.charcount; op.data = cfdarg.chardata; return con_font_op(fg_console, &op); case GIO_FONTX: if (!cfdarg.chardata) return 0; op.op = KD_FONT_OP_GET; op.flags = 0; op.width = 8; op.height = cfdarg.charheight; op.charcount = cfdarg.charcount; op.data = cfdarg.chardata; i = con_font_op(fg_console, &op); if (i) return i; cfdarg.charheight = op.height; cfdarg.charcount = op.charcount; ((struct consolefontdesc32 *)&cfdarg)->chardata = (unsigned long)cfdarg.chardata; if (copy_to_user(user_cfd, &cfdarg, sizeof(struct consolefontdesc32))) return -EFAULT; return 0; } return -EINVAL;}struct console_font_op32 { unsigned int op; /* operation code KD_FONT_OP_* */ unsigned int flags; /* KD_FONT_FLAG_* */ unsigned int width, height; /* font size */ unsigned int charcount; u32 data; /* font data with height fixed to 32 */}; static int do_kdfontop_ioctl(unsigned int fd, unsigned int cmd, struct console_font_op32 *fontop, struct file *file){ struct console_font_op op; int perm = vt_check(file), i; struct vt_struct *vt; if (perm < 0) return perm; if (copy_from_user(&op, (void *) fontop, sizeof(struct console_font_op32))) return -EFAULT; if (!perm && op.op != KD_FONT_OP_GET) return -EPERM; op.data = (unsigned char *)A(((struct console_font_op32 *)&op)->data); op.flags |= KD_FONT_FLAG_OLD; vt = (struct vt_struct *)((struct tty_struct *)file->private_data)->driver_data; i = con_font_op(vt->vc_num, &op); if (i) return i; ((struct console_font_op32 *)&op)->data = (unsigned long)op.data; if (copy_to_user((void *) fontop, &op, sizeof(struct console_font_op32))) return -EFAULT; return 0;}struct fb_fix_screeninfo32 { char id[16]; /* identification string eg "TT Builtin" */ unsigned int smem_start; /* Start of frame buffer mem */ /* (physical address) */ __u32 smem_len; /* Length of frame buffer mem */ __u32 type; /* see FB_TYPE_* */ __u32 type_aux; /* Interleave for interleaved Planes */ __u32 visual; /* see FB_VISUAL_* */ __u16 xpanstep; /* zero if no hardware panning */ __u16 ypanstep; /* zero if no hardware panning */ __u16 ywrapstep; /* zero if no hardware ywrap */ __u32 line_length; /* length of a line in bytes */ unsigned int mmio_start; /* Start of Memory Mapped I/O */ /* (physical address) */ __u32 mmio_len; /* Length of Memory Mapped I/O */ __u32 accel; /* Type of acceleration available */ __u16 reserved[3]; /* Reserved for future compatibility */};static int do_fbioget_fscreeninfo_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg){ mm_segment_t old_fs = get_fs(); struct fb_fix_screeninfo fix; int err; set_fs(KERNEL_DS); err = sys_ioctl(fd, cmd, (long)&fix); set_fs(old_fs); if (err == 0) { unsigned int smem_start = fix.smem_start; /* lose top 32 bits */ unsigned int mmio_start = fix.mmio_start; /* lose top 32 bits */ int i; err = put_user(fix.id[0], &((struct fb_fix_screeninfo32 *)arg)->id[0]); for (i=1; i<16; i++) { err |= __put_user(fix.id[i], &((struct fb_fix_screeninfo32 *)arg)->id[i]); } err |= __put_user(smem_start, &((struct fb_fix_screeninfo32 *)arg)->smem_start); err |= __put_user(fix.smem_len, &((struct fb_fix_screeninfo32 *)arg)->smem_len); err |= __put_user(fix.type, &((struct fb_fix_screeninfo32 *)arg)->type); err |= __put_user(fix.type_aux, &((struct fb_fix_screeninfo32 *)arg)->type_aux); err |= __put_user(fix.visual, &((struct fb_fix_screeninfo32 *)arg)->visual); err |= __put_user(fix.xpanstep, &((struct fb_fix_screeninfo32 *)arg)->xpanstep); err |= __put_user(fix.ypanstep, &((struct fb_fix_screeninfo32 *)arg)->ypanstep); err |= __put_user(fix.ywrapstep, &((struct fb_fix_screeninfo32 *)arg)->ywrapstep); err |= __put_user(fix.line_length, &((struct fb_fix_screeninfo32 *)arg)->line_length); err |= __put_user(mmio_start, &((struct fb_fix_screeninfo32 *)arg)->mmio_start); err |= __put_user(fix.mmio_len, &((struct fb_fix_screeninfo32 *)arg)->mmio_len); err |= __put_user(fix.accel, &((struct fb_fix_screeninfo32 *)arg)->accel); err |= __put_user(fix.reserved[0], &((struct fb_fix_screeninfo32 *)arg)->reserved[0]); err |= __put_user(fix.reserved[1], &((struct fb_fix_screeninfo32 *)arg)->reserved[1]); err |= __put_user(fix.reserved[2], &((struct fb_fix_screeninfo32 *)arg)->reserved[2]); if (err) err = -EFAULT; } return err;}struct fb_cmap32 { __u32 start; /* First entry */ __u32 len; /* Number of entries */ __u32 redptr; /* Red values */ __u32 greenptr; __u32 blueptr; __u32 transpptr; /* transparency, can be NULL */};static int do_fbiogetcmap_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg){ mm_segment_t old_fs = get_fs(); struct fb_cmap cmap; int err; set_fs(KERNEL_DS); err = sys_ioctl(fd, cmd, (long)&cmap); set_fs(old_fs); if (err == 0) { __u32 redptr = (__u32)(__u64)cmap.red; __u32 greenptr = (__u32)(__u64)cmap.green; __u32 blueptr = (__u32)(__u64)cmap.blue; __u32 transpptr = (__u32)(__u64)cmap.transp; err = put_user(cmap.start, &((struct fb_cmap32 *)arg)->start); err |= __put_user(cmap.len, &((struct fb_cmap32 *)arg)->len); err |= __put_user(redptr, &((struct fb_cmap32 *)arg)->redptr); err |= __put_user(greenptr, &((struct fb_cmap32 *)arg)->greenptr); err |= __put_user(blueptr, &((struct fb_cmap32 *)arg)->blueptr); err |= __put_user(transpptr, &((struct fb_cmap32 *)arg)->transpptr); if (err) err = -EFAULT; } return err;}static int do_fbioputcmap_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg){ mm_segment_t old_fs = get_fs(); struct fb_cmap cmap; __u32 redptr, greenptr, blueptr, transpptr; int err; err = get_user(cmap.start, &((struct fb_cmap32 *)arg)->start); err |= __get_user(cmap.len, &((struct fb_cmap32 *)arg)->len); err |= __get_user(redptr, &((struct fb_cmap32 *)arg)->redptr); err |= __get_user(greenptr, &((struct fb_cmap32 *)arg)->greenptr); err |= __get_user(blueptr, &((struct fb_cmap32 *)arg)->blueptr); err |= __get_user(transpptr, &((struct fb_cmap32 *)arg)->transpptr); if (err) { err = -EFAULT; } else { cmap.red = (__u16 *)(__u64)redptr; cmap.green = (__u16 *)(__u64)greenptr; cmap.blue = (__u16 *)(__u64)blueptr; cmap.transp = (__u16 *)(__u64)transpptr; set_fs (KERNEL_DS); err = sys_ioctl (fd, cmd, (unsigned long)&cmap); set_fs (old_fs); } return err;}struct unimapdesc32 { unsigned short entry_ct; u32 entries;};static int do_unimap_ioctl(unsigned int fd, unsigned int cmd, struct unimapdesc32 *user_ud, struct file *file){ struct unimapdesc32 tmp; int perm = vt_check(file); if (perm < 0) return perm; if (copy_from_user(&tmp, user_ud, sizeof tmp))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -