⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ioctl32.c

📁 linux-2.4.29操作系统的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	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;	unsigned char		data_direction;	int			quiet;	int			timeout;	__kernel_caddr_t32	reserved[1];};static int cdrom_do_read_audio(unsigned int fd, unsigned int cmd, unsigned long arg){	struct cdrom_read_audio *cdread_audio;	struct cdrom_read_audio32 *cdread_audio32;	__u32 data;	void *datap;	cdread_audio = alloc_user_space(sizeof(*cdread_audio));	cdread_audio32 = (struct cdrom_read_audio32 *) arg;	if (copy_in_user(&cdread_audio->addr,			 &cdread_audio32->addr,			 (sizeof(*cdread_audio32) -			  sizeof(__kernel_caddr_t32))))		return -EFAULT;	if (get_user(data, &cdread_audio32->buf))		return -EFAULT;	datap = (void *) (unsigned long) data;	if (put_user(datap, &cdread_audio->buf))		return -EFAULT;	return sys_ioctl(fd, cmd, (unsigned long) cdread_audio);}static int __cgc_do_ptr(void **ptr64, __u32 *ptr32){	u32 data;	void *datap;	if (get_user(data, ptr32))		return -EFAULT;	datap = (void *) (unsigned long) data;	if (put_user(datap, ptr64))		return -EFAULT;	return 0;}static int cdrom_do_generic_command(unsigned int fd, unsigned int cmd, unsigned long arg){	struct cdrom_generic_command *cgc;	struct cdrom_generic_command32 *cgc32;	unsigned char dir;	cgc = alloc_user_space(sizeof(*cgc));	cgc32 = (struct cdrom_generic_command32 *) arg;	if (copy_in_user(&cgc->cmd, &cgc32->cmd, sizeof(cgc->cmd)) ||	    __cgc_do_ptr((void **) &cgc->buffer, &cgc32->buffer) ||	    copy_in_user(&cgc->buflen, &cgc32->buflen,			 (sizeof(unsigned int) + sizeof(int))) ||	    __cgc_do_ptr((void **) &cgc->sense, &cgc32->sense))		return -EFAULT;	if (get_user(dir, &cgc32->data_direction) ||	    put_user(dir, &cgc->data_direction))		return -EFAULT;	if (copy_in_user(&cgc->quiet, &cgc32->quiet,			 2 * sizeof(int)))		return -EFAULT;	if (__cgc_do_ptr(&cgc->reserved[0], &cgc32->reserved[0]))		return -EFAULT;	return sys_ioctl(fd, cmd, (unsigned long) cgc);}static int cdrom_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg){	int err;	switch(cmd) {	case CDROMREADAUDIO:		err = cdrom_do_read_audio(fd, cmd, arg);		break;	case CDROM_SEND_PACKET:		err = cdrom_do_generic_command(fd, cmd, arg);		break;	default:		do {			static int count;			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);		err = -EINVAL;		break;	};	return err;}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;		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);static 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 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))		return -EFAULT;	switch (cmd) {	case PIO_UNIMAP:		if (!perm) return -EPERM;		return con_set_unimap(fg_console, tmp.entry_ct, (struct unipair *)A(tmp.entries));	case GIO_UNIMAP:		return con_get_unimap(fg_console, tmp.entry_ct, &(user_ud->entry_ct), (struct unipair *)A(tmp.entries));	}	return 0;}static int do_smb_getmountuid(unsigned int fd, unsigned int cmd, unsigned long arg){	mm_segment_t old_fs = get_fs();	__kernel_uid_t kuid;	int err;	cmd = SMB_IOC_GETMOUNTUID;	set_fs(KERNEL_DS);	err = sys_ioctl(fd, cmd, (unsigned long)&kuid);	set_fs(old_fs);	if (err >= 0)		err = put_user(kuid, (__kernel_uid_t32 *)arg);	return err;}struct ncp_ioctl_request_32 {	unsigned int function;	unsigned int size;	__kernel_caddr_t32 data;};struct ncp_fs_info_v2_32 {	int version;	unsigned int mounted_uid;	unsigned int connection;	unsigned int buffer_size;	unsigned int volume_number;	__u32 directory_id;	__u32 dummy1;	__u32 dummy2;	__u32 dummy3;};struct ncp_objectname_ioctl_32{	int		auth_type;	unsigned int	object_name_len;	__kernel_caddr_t32	object_name;	/* an userspace data, in most cases user name */};struct ncp_privatedata_ioctl_32{	unsigned int	len;	__kernel_caddr_t32	data;		/* ~1000 for NDS */};#define	NCP_IOC_NCPREQUEST_32		_IOR('n', 1, struct ncp_ioctl_request_32)#define NCP_IOC_GETMOUNTUID2_32		_IOW('n', 2, unsigned int)#define NCP_IOC_GET_FS_INFO_V2_32	_IOWR('n', 4, struct ncp_fs_info_v2_32)#define NCP_IOC_GETOBJECTNAME_32	_IOWR('n', 9, struct ncp_objectname_ioctl_32)#define NCP_IOC_SETOBJECTNAME_32	_IOR('n', 9, struct ncp_objectname_ioctl_32)#define NCP_IOC_GETPRIVATEDATA_32	_IOWR('n', 10, struct ncp_privatedata_ioctl_32)#define NCP_IOC_SETPRIVATEDATA_32	_IOR('n', 10, struct ncp_privatedata_ioctl_32)static int do_ncp_ncprequest(unsigned int fd, unsigned int cmd, unsigned long arg){	struct ncp_ioctl_request_32 n32;	struct ncp_ioctl_request n;	mm_segment_t old_fs;	int err;	if (copy_from_user(&n32, (struct ncp_ioctl_request_32*)arg,	    sizeof(n32)))		return -EFAULT;	n.function = n32.function;	n.size = n32.size;	if (n.size > 65536)		return -EINVAL;	n.data = vmalloc(65536);	/* 65536 must be same as NCP_PACKET_SIZE_INTERNAL in ncpfs */	if (!n.data)		return -ENOMEM;	err = -EFAULT;	if (copy_from_user(n.data, A(n32.data), n.size))		goto out;	old_fs = get_fs(); set_fs (KERNEL_DS);	err = sys_ioctl (fd, NCP_IOC_NCPREQUEST, (unsigned long)&n);	set_fs (old_fs);        if(err <= 0)		goto out;	if (err > 65536) {		err = -EINVAL;		goto out;	}	if (copy_to_user(A(n32.data), n.data, err)) {		err = -EFAULT;		goto out;	} out:	vfree(n.data);	return err;}static int do_ncp_getmountuid2(unsigned int fd, unsigned int cmd, unsigned long arg){	mm_segment_t old_fs = get_fs();	__kernel_uid_t kuid;	int err;	cmd = NCP_IOC_GETMOUNTUID2;	set_fs(KERNEL_DS);	err = sys_ioctl(fd, cmd, (unsigned long)&kuid);	set_fs(old_fs);	if (!err)		err = put_user(kuid, (unsigned int*)arg);	return err;}static int do_ncp_getfsinfo2(unsigned int fd, unsigned int cmd, unsigned long arg){	mm_segment_t old_fs = get_fs();	struct ncp_fs_info_v2_32 n32;	struct ncp_fs_info_v2 n;	int err;	if (copy_from_user(&n32, (struct ncp_fs_info_v2_32*)arg, sizeof(n32)))		return -EFAULT;	if (n32.version != NCP_GET_FS_INFO_VERSION_V2)		return -EINVAL;	n.version = NCP_GET_FS_INFO_VERSION_V2;	set_fs(KERNEL_DS);	err = sys_ioctl(fd, NCP_IOC_GET_FS_INFO_V2, (unsigned long)&n);	set_fs(old_fs);	if (!err) {		n32.version = n.version;		n32.mounted_uid = n.mounted_uid;		n32.connection = n.connection;		n32.buffer_size = n.buffer_size;		n32.volume_number = n.volume_number;		n32.directory_id = n.directory_id;		n32.dummy1 = n.dummy1;		n32.dummy2 = n.dummy2;		n32.dummy3 = n.dummy3;		err = copy_to_user((struct ncp_fs_info_v2_32*)arg, &n32, sizeof(n32)) ? -EFAULT : 0;	}	return err;}static int do_ncp_getobjectname(unsigned int fd, unsigned int cmd, uns

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -